mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-07 13:44:54 +03:00
Tied schema dropdown to request/response schema samples
This commit is contained in:
parent
e39bdc244d
commit
06f372d1a8
|
@ -24,6 +24,8 @@ export class JsonSchemaLazy implements OnDestroy, OnInit, AfterViewInit {
|
||||||
@Input() nestOdd: boolean;
|
@Input() nestOdd: boolean;
|
||||||
@Input() childFor: string;
|
@Input() childFor: string;
|
||||||
@Input() isArray: boolean;
|
@Input() isArray: boolean;
|
||||||
|
@Input() responseCode:string;
|
||||||
|
|
||||||
disableLazy: boolean = false;
|
disableLazy: boolean = false;
|
||||||
loaded: boolean = false;
|
loaded: boolean = false;
|
||||||
constructor(private specMgr:SpecManager, private location:ViewContainerRef, private elementRef:ElementRef,
|
constructor(private specMgr:SpecManager, private location:ViewContainerRef, private elementRef:ElementRef,
|
||||||
|
|
|
@ -12,8 +12,7 @@ import { Component,
|
||||||
import { BaseSearchableComponent, SpecManager } from '../base';
|
import { BaseSearchableComponent, SpecManager } from '../base';
|
||||||
import { SchemaNormalizer, SchemaHelper, AppStateService, OptionsService } from '../../services/';
|
import { SchemaNormalizer, SchemaHelper, AppStateService, OptionsService } from '../../services/';
|
||||||
import { JsonPointer, DescendantInfo } from '../../utils/';
|
import { JsonPointer, DescendantInfo } from '../../utils/';
|
||||||
import { Zippy } from '../../shared/components';
|
import {SchemaChangerService} from "../../services/schema-changer.service";
|
||||||
import { JsonSchemaLazy } from './json-schema-lazy';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'json-schema',
|
selector: 'json-schema',
|
||||||
|
@ -28,6 +27,7 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
||||||
@Input() nestOdd: boolean;
|
@Input() nestOdd: boolean;
|
||||||
@Input() childFor: string;
|
@Input() childFor: string;
|
||||||
@Input() isRequestSchema: boolean;
|
@Input() isRequestSchema: boolean;
|
||||||
|
@Input() responseCode: string;
|
||||||
|
|
||||||
schema: any = {};
|
schema: any = {};
|
||||||
activeDescendant:any = {};
|
activeDescendant:any = {};
|
||||||
|
@ -44,7 +44,8 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
||||||
private _renderer: Renderer,
|
private _renderer: Renderer,
|
||||||
private cdr: ChangeDetectorRef,
|
private cdr: ChangeDetectorRef,
|
||||||
private _elementRef: ElementRef,
|
private _elementRef: ElementRef,
|
||||||
private optionsService: OptionsService) {
|
private optionsService: OptionsService,
|
||||||
|
private _schemaChanger: SchemaChangerService) {
|
||||||
super(specMgr, app);
|
super(specMgr, app);
|
||||||
this.normalizer = new SchemaNormalizer(specMgr);
|
this.normalizer = new SchemaNormalizer(specMgr);
|
||||||
}
|
}
|
||||||
|
@ -55,6 +56,9 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
|
||||||
|
|
||||||
selectDescendantByIdx(idx) {
|
selectDescendantByIdx(idx) {
|
||||||
this.selectDescendant(this.descendants[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) {
|
selectDescendant(activeDescendant: DescendantInfo) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Input, HostBinding, Component, OnInit, ChangeDetectionStrategy, Element
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
import { BaseComponent, SpecManager } from '../base';
|
import { BaseComponent, SpecManager } from '../base';
|
||||||
import { SchemaHelper } from '../../services/schema-helper.service';
|
import { SchemaHelper } from '../../services/schema-helper.service';
|
||||||
import { OptionsService, MenuService } from '../../services/';
|
import { OptionsService, MenuService, SchemaChangerService } from '../../services/';
|
||||||
import { SwaggerBodyParameter } from '../../utils/swagger-typings';
|
import { SwaggerBodyParameter } from '../../utils/swagger-typings';
|
||||||
|
|
||||||
export interface OperationInfo {
|
export interface OperationInfo {
|
||||||
|
@ -27,7 +27,8 @@ export interface OperationInfo {
|
||||||
selector: 'operation',
|
selector: 'operation',
|
||||||
templateUrl: './operation.html',
|
templateUrl: './operation.html',
|
||||||
styleUrls: ['./operation.css'],
|
styleUrls: ['./operation.css'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
providers: [SchemaChangerService]
|
||||||
})
|
})
|
||||||
export class Operation extends BaseComponent implements OnInit {
|
export class Operation extends BaseComponent implements OnInit {
|
||||||
@Input() pointer :string;
|
@Input() pointer :string;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<header *ngIf="schemaPointer || samples.length"> Request samples </header>
|
<header *ngIf="schemaPointer || samples.length"> Request samples </header>
|
||||||
<schema-sample *ngIf="schemaPointer && !samples.length" [skipReadOnly]="true" [pointer]="schemaPointer"> </schema-sample>
|
<schema-sample *ngIf="schemaPointer && !samples.length" [skipReadOnly]="true" [pointer]="schemaPointer" [isRequestSample]="true"> </schema-sample>
|
||||||
<tabs *ngIf="samples.length" [selected] = "selectedLang" (change)=changeLangNotify($event)>
|
<tabs *ngIf="samples.length" [selected] = "selectedLang" (change)=changeLangNotify($event)>
|
||||||
<tab *ngIf="schemaPointer" tabTitle="JSON">
|
<tab *ngIf="schemaPointer" tabTitle="JSON">
|
||||||
<schema-sample [pointer]="schemaPointer" [skipReadOnly]="true"> </schema-sample>
|
<schema-sample [pointer]="schemaPointer" [skipReadOnly]="true" [isRequestSample]="true"> </schema-sample>
|
||||||
</tab>
|
</tab>
|
||||||
<tab *ngFor="let sample of samples" [tabTitle]="sample.lang">
|
<tab *ngFor="let sample of samples" [tabTitle]="sample.lang">
|
||||||
<div class="code-sample">
|
<div class="code-sample">
|
||||||
|
|
|
@ -21,6 +21,6 @@
|
||||||
Response Schema
|
Response Schema
|
||||||
</header>
|
</header>
|
||||||
<json-schema-lazy [auto]="response.expanded" #lazySchema
|
<json-schema-lazy [auto]="response.expanded" #lazySchema
|
||||||
pointer="{{response.schema ? response.pointer + '/schema' : null}}">
|
pointer="{{response.schema ? response.pointer + '/schema' : null}}" [responseCode]="response.code">
|
||||||
</json-schema-lazy>
|
</json-schema-lazy>
|
||||||
</zippy>
|
</zippy>
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
<tabs *ngIf="data.responses.length">
|
<tabs *ngIf="data.responses.length">
|
||||||
<tab *ngFor="let response of data.responses" [tabTitle]="response.code + ' ' + response.description | marked"
|
<tab *ngFor="let response of data.responses" [tabTitle]="response.code + ' ' + response.description | marked"
|
||||||
[tabStatus]="response.type">
|
[tabStatus]="response.type">
|
||||||
<schema-sample [pointer]="response.pointer"></schema-sample>
|
<schema-sample [pointer]="response.pointer" [isRequestSample]="false" [responseCode]="response.code"></schema-sample>
|
||||||
</tab>
|
</tab>
|
||||||
</tabs>
|
</tabs>
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
'use strict';
|
'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 * as OpenAPISampler from 'openapi-sampler';
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
import { BaseComponent, SpecManager } from '../base';
|
import {BaseComponent, SpecManager} from '../base';
|
||||||
import { SchemaNormalizer } from '../../services/schema-normalizer.service';
|
import {SchemaNormalizer} from '../../services/schema-normalizer.service';
|
||||||
import { getJsonLikeSample, getXmlLikeSample, getTextLikeSample } from '../../utils/helpers';
|
import {getJsonLikeSample, getXmlLikeSample, getTextLikeSample} from '../../utils/helpers';
|
||||||
|
|
||||||
|
import {Subscription} from 'rxjs/Subscription';
|
||||||
|
import {SchemaChangerService} from "../../services/schema-changer.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'schema-sample',
|
selector: 'schema-sample',
|
||||||
|
@ -15,8 +18,11 @@ import { getJsonLikeSample, getXmlLikeSample, getTextLikeSample } from '../../ut
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class SchemaSample extends BaseComponent implements OnInit {
|
export class SchemaSample extends BaseComponent implements OnInit {
|
||||||
@Input() pointer:string;
|
@Input() pointer: string;
|
||||||
@Input() skipReadOnly:boolean;
|
@Input() skipReadOnly: boolean;
|
||||||
|
@Input() subscription: Subscription;
|
||||||
|
@Input() isRequestSample: boolean;
|
||||||
|
@Input() responseCode: string;
|
||||||
|
|
||||||
element: any;
|
element: any;
|
||||||
sample: any;
|
sample: any;
|
||||||
|
@ -24,18 +30,36 @@ export class SchemaSample extends BaseComponent implements OnInit {
|
||||||
textSample: string;
|
textSample: string;
|
||||||
enableButtons: boolean = false;
|
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);
|
super(specMgr);
|
||||||
this.element = elementRef.nativeElement;
|
this.element = elementRef.nativeElement;
|
||||||
this._normalizer = new SchemaNormalizer(specMgr);
|
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() {
|
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();
|
this.bindEvents();
|
||||||
|
|
||||||
let base:any = this.componentSchema;
|
let base: any = this.componentSchema;
|
||||||
let sample, xmlSample;
|
let sample, xmlSample;
|
||||||
|
|
||||||
// got pointer not directly to the schema but e.g. to the response obj
|
// 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.
|
// Support x-examples, allowing requests to specify an example.
|
||||||
let examplePointer:string = JsonPointer.join(JsonPointer.dirName(this.pointer), 'x-examples');
|
let examplePointer: string = JsonPointer.join(JsonPointer.dirName(this.pointer), 'x-examples');
|
||||||
let requestExamples:any = this.specMgr.byPointer(examplePointer);
|
let requestExamples: any = this.specMgr.byPointer(examplePointer);
|
||||||
if (requestExamples) {
|
if (requestExamples) {
|
||||||
base.examples = requestExamples;
|
base.examples = requestExamples;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +79,10 @@ export class SchemaSample extends BaseComponent implements OnInit {
|
||||||
this.xmlSample = base.examples && getXmlLikeSample(base.examples);
|
this.xmlSample = base.examples && getXmlLikeSample(base.examples);
|
||||||
this.textSample = base.examples && getTextLikeSample(base.examples);
|
this.textSample = base.examples && getTextLikeSample(base.examples);
|
||||||
|
|
||||||
|
if (this.fromCache()) {
|
||||||
|
this.initButtons();
|
||||||
|
return;
|
||||||
|
}
|
||||||
let jsonLikeSample = base.examples && getJsonLikeSample(base.examples);
|
let jsonLikeSample = base.examples && getJsonLikeSample(base.examples);
|
||||||
if (jsonLikeSample) {
|
if (jsonLikeSample) {
|
||||||
sample = jsonLikeSample;
|
sample = jsonLikeSample;
|
||||||
|
@ -67,22 +95,23 @@ export class SchemaSample extends BaseComponent implements OnInit {
|
||||||
if (discriminator) {
|
if (discriminator) {
|
||||||
let descendants = this.specMgr.findDerivedDefinitions(this.componentSchema._pointer || this.pointer, this.componentSchema);
|
let descendants = this.specMgr.findDerivedDefinitions(this.componentSchema._pointer || this.pointer, this.componentSchema);
|
||||||
if (descendants.length) {
|
if (descendants.length) {
|
||||||
// TODO: sync up with dropdown
|
selectedDescendant = descendants[descendantIdx];
|
||||||
selectedDescendant = descendants[0];
|
//use this block to ignore lazy loaded dropdowns for now
|
||||||
let descSchema = this.specMgr.getDescendant(selectedDescendant, this.componentSchema);
|
if (descendantName == null ||
|
||||||
this.componentSchema = this._normalizer.normalize(Object.assign({}, descSchema), selectedDescendant.$ref,
|
(selectedDescendant && selectedDescendant.name === descendantName)) {
|
||||||
{omitParent: false});
|
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 {
|
try {
|
||||||
sample = OpenAPISampler.sample(this.componentSchema, {
|
sample = OpenAPISampler.sample(this.componentSchema, {
|
||||||
skipReadOnly: this.skipReadOnly
|
skipReadOnly: this.skipReadOnly
|
||||||
});
|
});
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
// no sample available
|
// no sample available
|
||||||
}
|
}
|
||||||
if (selectedDescendant) {
|
if (selectedDescendant) {
|
||||||
|
@ -153,4 +182,8 @@ export class SchemaSample extends BaseComponent implements OnInit {
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.preinit();
|
this.preinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ export * from './schema-helper.service';
|
||||||
export * from './warnings.service';
|
export * from './warnings.service';
|
||||||
export * from './search.service';
|
export * from './search.service';
|
||||||
|
|
||||||
|
export * from './schema-changer.service';
|
||||||
export * from './component-parser.service';
|
export * from './component-parser.service';
|
||||||
export * from './content-projector.service';
|
export * from './content-projector.service';
|
||||||
export * from './marker.service';
|
export * from './marker.service';
|
||||||
|
|
20
lib/services/schema-changer.service.ts
Normal file
20
lib/services/schema-changer.service.ts
Normal file
|
@ -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<any>();
|
||||||
|
|
||||||
|
// 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});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user