mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-10-31 15:57:30 +03:00 
			
		
		
		
	Implement expanding subschemas (fixes #56)
This commit is contained in:
		
							parent
							
								
									9e1d7768d7
								
							
						
					
					
						commit
						0b0f28cd4a
					
				|  | @ -11,16 +11,6 @@ $param-name-height: 20px; | ||||||
| 
 | 
 | ||||||
| $sub-schema-offset: ($bullet-size/2) + $bullet-margin; | $sub-schema-offset: ($bullet-size/2) + $bullet-margin; | ||||||
| 
 | 
 | ||||||
| /* |  | ||||||
| .param-schema { |  | ||||||
|   padding-left: $sub-schema-offset - $lines-width; |  | ||||||
|   border-left: $line-border; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .param-wrap { |  | ||||||
|   position: relative; |  | ||||||
| }*/ |  | ||||||
| 
 |  | ||||||
| .param-name { | .param-name { | ||||||
| 
 | 
 | ||||||
|   font-size: 0.929em; |   font-size: 0.929em; | ||||||
|  | @ -34,7 +24,7 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin; | ||||||
|   vertical-align: top; |   vertical-align: top; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .param-name-content { | .param-name-wrap { | ||||||
|   padding-right: $cell-spacing; |   padding-right: $cell-spacing; | ||||||
|   display: inline-block; |   display: inline-block; | ||||||
|   font-family: $headers-font, $headers-font-family; |   font-family: $headers-font, $headers-font-family; | ||||||
|  | @ -45,6 +35,7 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin; | ||||||
|   box-sizing: border-box; |   box-sizing: border-box; | ||||||
|   border-bottom: 1px solid #ccc; |   border-bottom: 1px solid #ccc; | ||||||
|   width: 75%; |   width: 75%; | ||||||
|  |   line-height: 1em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .param-range { | .param-range { | ||||||
|  |  | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| import { Component, ElementRef, ViewContainerRef, OnDestroy, AfterViewInit } from '@angular/core'; | import { Component, ElementRef, ViewContainerRef, OnDestroy, Input, | ||||||
|  |   AfterViewInit, ComponentResolver, Renderer } from '@angular/core'; | ||||||
| import { CORE_DIRECTIVES } from '@angular/common'; | import { CORE_DIRECTIVES } from '@angular/common'; | ||||||
| import { DynamicComponentLoader, Input } from '@angular/core'; |  | ||||||
| 
 | 
 | ||||||
| import { JsonSchema } from './json-schema'; | import { JsonSchema } from './json-schema'; | ||||||
| import { OptionsService } from '../../services/options.service'; | import { OptionsService } from '../../services/options.service'; | ||||||
|  | @ -19,9 +19,13 @@ export class JsonSchemaLazy implements OnDestroy, AfterViewInit { | ||||||
|   @Input() pointer: string; |   @Input() pointer: string; | ||||||
|   @Input() auto: boolean; |   @Input() auto: boolean; | ||||||
|   @Input() isRequestSchema: boolean; |   @Input() isRequestSchema: boolean; | ||||||
|  |   @Input() final: boolean = false; | ||||||
|  |   @Input() nestOdd: boolean; | ||||||
|  |   @Input() childFor: string; | ||||||
|  |   @Input() isArray: boolean; | ||||||
|   loaded: boolean = false; |   loaded: boolean = false; | ||||||
|   constructor(private specMgr:SpecManager, private viewRef:ViewContainerRef, private elementRef:ElementRef, |   constructor(private specMgr:SpecManager, private location:ViewContainerRef, private elementRef:ElementRef, | ||||||
|     private dcl:DynamicComponentLoader, private optionsService:OptionsService) { |     private resolver:ComponentResolver, private optionsService:OptionsService, private _renderer: Renderer) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   normalizePointer() { |   normalizePointer() { | ||||||
|  | @ -31,13 +35,15 @@ export class JsonSchemaLazy implements OnDestroy, AfterViewInit { | ||||||
| 
 | 
 | ||||||
|   _loadAfterSelf() { |   _loadAfterSelf() { | ||||||
|     // FIXME: get rid of DynamicComponentLoader as it is deprecated
 |     // FIXME: get rid of DynamicComponentLoader as it is deprecated
 | ||||||
|     return this.dcl.loadNextToLocation(JsonSchema, this.viewRef).then(compRef => { |     return this.resolver.resolveComponent(JsonSchema).then(componentFactory => { | ||||||
|       this.initComponent(compRef); |       let contextInjector = this.location.parentInjector; | ||||||
|       if (compRef.changeDetectorRef) { |       let compRef = this.location.createComponent( | ||||||
|         compRef.changeDetectorRef.detectChanges(); |           componentFactory, null, contextInjector, null); | ||||||
|       } |       this.initComponent(compRef.instance); | ||||||
|  |       this._renderer.setElementAttribute(compRef.location.nativeElement, 'class', this.location.element.nativeElement.className); | ||||||
|  |       compRef.changeDetectorRef.markForCheck(); | ||||||
|       return compRef; |       return compRef; | ||||||
|     }, err => { |     }).catch(err => { | ||||||
|       console.log(err); |       console.log(err); | ||||||
|       throw err; |       throw err; | ||||||
|     }); |     }); | ||||||
|  | @ -74,9 +80,8 @@ export class JsonSchemaLazy implements OnDestroy, AfterViewInit { | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   initComponent(compRef) { |   initComponent(instance:JsonSchema) { | ||||||
|     compRef.instance.pointer = this.pointer; |     Object.assign(instance, this); | ||||||
|     compRef.instance.isRequestSchema = this.isRequestSchema; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngAfterViewInit() { |   ngAfterViewInit() { | ||||||
|  |  | ||||||
|  | @ -19,14 +19,20 @@ | ||||||
| </span> | </span> | ||||||
| <table *ngIf="!schema.isTrivial" class="params-wrap" [ngClass]="{'params-array': schema._isArray}"> | <table *ngIf="!schema.isTrivial" class="params-wrap" [ngClass]="{'params-array': schema._isArray}"> | ||||||
|   <!-- <caption> {{_displayType}} </caption> --> |   <!-- <caption> {{_displayType}} </caption> --> | ||||||
|   <template ngFor [ngForOf]="schema._properties" let-prop="$implicit" let-last="last"> |   <template ngFor [ngForOf]="schema._properties" let-prop="$implicit" let-last="last" [ngForTrackBy]="trackByName"> | ||||||
|     <tr class="param" [ngClass]="{'last': last, |     <tr class="param" [ngClass]="{'last': last, | ||||||
|         'discriminator': hasDescendants && !activeDescendant.empty, |         'discriminator': prop.isDiscriminator, | ||||||
|         'complex': prop._pointer, |         'complex': prop._pointer, | ||||||
|         'additional': prop._additional |         'additional': prop._additional, | ||||||
|  |         'expanded': subSchema.visible | ||||||
|       }"> |       }"> | ||||||
|       <td class="param-name"> |       <td class="param-name"> | ||||||
|         <span class="param-name-content">{{prop._name}}</span> |         <span class="param-name-wrap"> | ||||||
|  |           <span (click)="subSchema.toggle()" class="param-name-content" >{{prop._name}}</span> | ||||||
|  |           <svg *ngIf="prop._pointer" xmlns="http://www.w3.org/2000/svg" version="1.1" x="0" y="0" viewBox="0 0 24 24" xml:space="preserve"> | ||||||
|  |             <polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "/> | ||||||
|  |           </svg> | ||||||
|  |         </span> | ||||||
|       </td> |       </td> | ||||||
|       <td class="param-info"> |       <td class="param-info"> | ||||||
|         <div> |         <div> | ||||||
|  | @ -50,11 +56,13 @@ | ||||||
|         </div> |         </div> | ||||||
|       </td> |       </td> | ||||||
|     </tr> |     </tr> | ||||||
|     <tr class="param-schema" [ngClass]="{'param-array': prop._isArray, 'last': last}" *ngIf="prop._pointer"> |     <tr class="param-schema" [ngClass]="{'param-array': prop._isArray, 'last': last}" [hidden]="!prop._pointer"> | ||||||
|       <td colspan="2"> |       <td colspan="2"> | ||||||
|         <json-schema class="nested-schema" pointer="{{prop._pointer}}" [isArray]='prop._isArray' |         <zippy #subSchema title="test" [headless]="true" (open)="lazySchema.load()"> | ||||||
|         [nestOdd]="!nestOdd" [isRequestSchema]="isRequestSchema" [attr.nesteven]="!nestOdd"> |           <json-schema-lazy #lazySchema class="nested-schema" pointer="{{prop._pointer}}" [isArray]='prop._isArray' | ||||||
|         </json-schema> |           [nestOdd]="!nestOdd" [isRequestSchema]="isRequestSchema"> | ||||||
|  |           </json-schema-lazy> | ||||||
|  |         </zippy> | ||||||
|       </td> |       </td> | ||||||
|     </tr> |     </tr> | ||||||
|   </template> |   </template> | ||||||
|  |  | ||||||
|  | @ -19,7 +19,7 @@ $array-marker-line-height: 1.5; | ||||||
|   display: block; |   display: block; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json-schema.nested-schema { | :host.nested-schema { | ||||||
|   background-color: white; |   background-color: white; | ||||||
|   padding: 10px 20px; |   padding: 10px 20px; | ||||||
|   position: relative; |   position: relative; | ||||||
|  | @ -50,7 +50,7 @@ json-schema.nested-schema { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json-schema[nesteven="true"] { | :host[nestodd="true"]  { | ||||||
|   background-color: $side-menu-active-bg-color; |   background-color: $side-menu-active-bg-color; | ||||||
|   border-radius: $border-radius; |   border-radius: $border-radius; | ||||||
| 
 | 
 | ||||||
|  | @ -69,10 +69,29 @@ json-schema[nesteven="true"] { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .param.complex > .param-info { | .zippy-content-wrap { | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .param.complex.expanded > .param-info { | ||||||
|   border-bottom: 0; |   border-bottom: 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .param.complex > .param-name .param-name-content { | ||||||
|  |   font-weight: bold; | ||||||
|  |   cursor: pointer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .param.complex > .param-name svg { | ||||||
|  |   height: 1.2em; | ||||||
|  |   vertical-align: middle; | ||||||
|  |   transition: all 0.3s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .param.complex.expanded > .param-name svg{ | ||||||
|  |   transform: rotateZ(-180deg); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .param.additional > .param-name { | .param.additional > .param-name { | ||||||
|   color: rgba($black, 0.4); |   color: rgba($black, 0.4); | ||||||
| } | } | ||||||
|  | @ -127,7 +146,6 @@ json-schema[nesteven="true"] { | ||||||
| .param.discriminator { | .param.discriminator { | ||||||
|   > .param-info { |   > .param-info { | ||||||
|     padding-bottom: 0; |     padding-bottom: 0; | ||||||
|     border-bottom: 0; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   > .param-name:after { |   > .param-name:after { | ||||||
|  |  | ||||||
|  | @ -1,16 +1,18 @@ | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| import { Input } from '@angular/core'; | import { Input, Renderer, ElementRef } from '@angular/core'; | ||||||
| 
 | 
 | ||||||
| import { RedocComponent, BaseComponent, SpecManager } from '../base'; | import { RedocComponent, BaseComponent, SpecManager } from '../base'; | ||||||
| import { DropDown } from '../../shared/components/index'; | import { DropDown } from '../../shared/components/index'; | ||||||
| import { SchemaNormalizer, SchemaHelper } from '../../services/index'; | import { SchemaNormalizer, SchemaHelper } from '../../services/index'; | ||||||
|  | import { JsonSchemaLazy } from './json-schema-lazy'; | ||||||
|  | import { Zippy } from '../../shared/components/Zippy/zippy'; | ||||||
| 
 | 
 | ||||||
| @RedocComponent({ | @RedocComponent({ | ||||||
|   selector: 'json-schema', |   selector: 'json-schema', | ||||||
|   templateUrl: './json-schema.html', |   templateUrl: './json-schema.html', | ||||||
|   styleUrls: ['./json-schema.css'], |   styleUrls: ['./json-schema.css'], | ||||||
|   directives: [JsonSchema, DropDown], |   directives: [JsonSchema, DropDown, JsonSchemaLazy, Zippy], | ||||||
|   detect: true |   detect: true | ||||||
| }) | }) | ||||||
| export class JsonSchema extends BaseComponent { | export class JsonSchema extends BaseComponent { | ||||||
|  | @ -24,7 +26,7 @@ export class JsonSchema extends BaseComponent { | ||||||
|   @Input() isRequestSchema: boolean; |   @Input() isRequestSchema: boolean; | ||||||
|   normalizer: SchemaNormalizer; |   normalizer: SchemaNormalizer; | ||||||
| 
 | 
 | ||||||
|   constructor(specMgr:SpecManager) { |   constructor(specMgr:SpecManager, private _renderer: Renderer, private _elementRef: ElementRef) { | ||||||
|     super(specMgr); |     super(specMgr); | ||||||
|     this.normalizer = new SchemaNormalizer(specMgr); |     this.normalizer = new SchemaNormalizer(specMgr); | ||||||
|   } |   } | ||||||
|  | @ -63,6 +65,9 @@ export class JsonSchema extends BaseComponent { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   prepareModel() { |   prepareModel() { | ||||||
|  |     if (this.nestOdd) { | ||||||
|  |       this._renderer.setElementAttribute(this._elementRef.nativeElement, 'nestodd', 'true'); | ||||||
|  |     } | ||||||
|     this.schema = this.componentSchema; |     this.schema = this.componentSchema; | ||||||
|     if (!this.schema) { |     if (!this.schema) { | ||||||
|       throw new Error(`Can't load component schema at ${this.pointer}`); |       throw new Error(`Can't load component schema at ${this.pointer}`); | ||||||
|  | @ -81,4 +86,8 @@ export class JsonSchema extends BaseComponent { | ||||||
| 
 | 
 | ||||||
|     this.initDescendants(); |     this.initDescendants(); | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   trackByName(index: number, item: any): string { | ||||||
|  |     return item['name']; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
|   <div class="params-wrap"> |   <div class="params-wrap"> | ||||||
|     <div *ngFor="let param of paramType.params" class="param"> |     <div *ngFor="let param of paramType.params" class="param"> | ||||||
|         <div class="param-name"> |         <div class="param-name"> | ||||||
|           <span class="param-name-content"> {{param.name}} </span> |           <span class="param-name-wrap"> {{param.name}} </span> | ||||||
|         </div> |         </div> | ||||||
|         <div class="param-info"> |         <div class="param-info"> | ||||||
|           <div> |           <div> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user