'use strict'; import {RedocComponent, BaseComponent} from '../base'; import {Tabs, Tab} from '../../common/components/Tabs/tabs'; import {ElementRef} from 'angular2/core'; import JsonPointer from '../../utils/JsonPointer'; @RedocComponent({ selector: 'json-schema', templateUrl: './lib/components/JsonSchema/json-schema.html', styleUrls: ['./lib/components/JsonSchema/json-schema.css'], directives: [JsonSchema, Tabs, Tab], inputs: ['isArray', 'final'] }) export default class JsonSchema extends BaseComponent { constructor(schemaMgr, elementRef) { super(schemaMgr); this.element = elementRef.nativeElement; this.final = false; } prepareModel() { this.data = {}; this.data.properties = []; this.data.derived = []; if (!this.componentSchema) { throw new Error(`Can't load component schema at ${this.pointer}`); } this.dereference(); let schema = this.componentSchema; if (schema.type === 'array') { this.isArray = true; schema = schema.items; } let normPtr = schema._pointer || this.pointer; let derived = this.schemaMgr.findDerivedDefinitions( normPtr ); if (!this.final && derived.length) { derived.unshift({ name: JsonPointer.baseName(normPtr), $ref: normPtr, final: true }); this.data.derived = derived; this.data.discriminator = schema.discriminator; return; } this.joinAllOf(schema); if (schema.type !== 'object') { this.isTrivial = true; this._displayType = schema.type; if (schema.format) this._displayType = `${this.displayType} <${schema.format}>`; return; } this.pointer = schema._pointer || this.pointer; this.requiredMap = {}; if (this.schema.required) { this.schema.required.forEach(prop => this.requiredMap[prop] = true); } if (!schema.properties) { this.isTrivial = true; this._displayType = `${schema.type} (Custom key-value pairs)`; return; } let props = Object.keys(schema.properties).map(prop => { let propData = schema.properties[prop]; this.injectPropData(prop, propData); return propData; }); this.data.properties = props; } adjustNameColumnWidth() { // TODO handle internal schemes differently let names = [].slice.call(this.element.querySelectorAll('.param-name')); let widths = names.map(el => el.offsetWidth); let maxWidth = Math.max(...widths); if (!maxWidth) return; names.forEach(el => { el.style.minWidth = maxWidth + 'px'; }); } injectPropData(prop, propData) { propData._name = prop; propData.isRequired = this.requiredMap[prop]; propData._displayType = propData.type; if (propData.type === 'array') { let itemType = propData.items.type; let itemFormat = propData.items.format; if (itemType === 'object') { itemType = propData.items.title || 'object'; propData._pointer = propData.items._pointer || JsonPointer.join(this.pointer, ['properties', prop, 'items']); } propData._displayType = `array of ${itemType}`; propData.format = itemFormat; propData._isArray = true; } if (propData.type === 'object') { propData._displayType = propData.title || 'object'; } if (propData.format) propData._displayFormat = `<${propData.format}>`; } init() { setTimeout(() => this.adjustNameColumnWidth()); } } JsonSchema.parameters = JsonSchema.parameters.concat([[ElementRef]]);