This commit is contained in:
Matthias Benkort 2017-07-20 14:57:55 +00:00 committed by GitHub
commit dae8fbfde4
6 changed files with 194 additions and 23 deletions

View File

@ -292,6 +292,76 @@ paths:
- petstore_auth: - petstore_auth:
- 'write:pets' - 'write:pets'
- 'read:pets' - 'read:pets'
'/pet/{petId}/behaviors':
put:
tags:
- pet
summary: Change behaviors
description: Update the pet's behaviors
operationId: updateBehavior
produces:
- application/xml
- application/json
parameters:
- name: petId
in: path
description: ID of pet to return
required: true
type: integer
format: int64
- name: body
in: body
required: true
schema:
oneOf:
- $ref: "#/definitions/CatBehavior"
- $ref: "#/definitions/DogBehavior"
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/Pet'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
security:
- api_key: []
post:
tags:
- pet
summary: Updates a pet in the store with form data
description: ''
operationId: updatePetWithForm
consumes:
- application/x-www-form-urlencoded
produces:
- application/xml
- application/json
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
type: integer
format: int64
- name: name
in: formData
description: Updated name of the pet
required: false
type: string
- name: status
in: formData
description: Updated status of the pet
required: false
type: string
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
/pet/findByStatus: /pet/findByStatus:
get: get:
tags: tags:
@ -655,12 +725,34 @@ definitions:
type: string type: string
message: message:
type: string type: string
CatBehavior:
type: object
properties:
mainTrait:
type: string
enum:
- cuddly
- aggressive
- lazy
dangerous:
type: boolean
Cat: Cat:
description: A representation of a cat description: A representation of a cat
allOf: allOf:
- $ref: '#/definitions/Pet' - $ref: '#/definitions/Pet'
- type: object - type: object
properties: properties:
behaviors:
type: array
default: []
description: A list of behaviors for this Cat
items:
$ref: "#/definitions/CatBehavior"
huntingSkill: huntingSkill:
type: string type: string
description: The measured skill for hunting description: The measured skill for hunting
@ -670,6 +762,7 @@ definitions:
- lazy - lazy
- adventurous - adventurous
- aggressive - aggressive
required: required:
- huntingSkill - huntingSkill
Category: Category:
@ -692,12 +785,32 @@ definitions:
description: Dumb Property description: Dumb Property
xml: xml:
name: Category name: Category
DogBehavior:
type: object
properties:
mainTrait:
type: string
enum:
- noisy
- slimy
- dependent
dangerous:
type: boolean
Dog: Dog:
description: A representation of a dog description: A representation of a dog
allOf: allOf:
- $ref: '#/definitions/Pet' - $ref: '#/definitions/Pet'
- type: object - type: object
properties: properties:
behaviors:
type: array
default: []
description: A list of behaviors for this Dog
items:
$ref: "#/definitions/DogBehavior"
packSize: packSize:
type: integer type: integer
format: int32 format: int32

View File

@ -46,9 +46,17 @@
[nestOdd]="!nestOdd" [isRequestSchema]="isRequestSchema"> </json-schema> [nestOdd]="!nestOdd" [isRequestSchema]="isRequestSchema"> </json-schema>
</ng-template> </ng-template>
<ng-template ngSwitchCase="object"> <ng-template ngSwitchCase="object">
<div class="one-of-selector" *ngIf="schema._wrapped.length > 1">
{{schema._choiceTitle}}
<drop-down (change)="selectChoice($event)" [active]="activeChoice">
<option *ngFor="let item of schema._wrapped; let i=index"
[value]="i" [attr.selected]="activeChoice === i ? '' : null" >{{item.title}}</option>
</drop-down>
</div>
<table class="params-wrap" [ngClass]="{'params-array': _isArray}"> <table class="params-wrap" [ngClass]="{'params-array': _isArray}">
<!-- <caption> {{_displayType}} </caption> --> <!-- <caption> {{_displayType}} </caption> -->
<ng-template ngFor [ngForOf]="properties" let-prop="$implicit" let-last="last" [ngForTrackBy]="trackByName"> <ng-template ngFor [ngForOf]="schema._wrapped[activeChoice].displayProperties" let-prop="$implicit" let-last="last" [ngForTrackBy]="trackByName">
<tr class="param" [ngClass]="{'last': last, <tr class="param" [ngClass]="{'last': last,
'discriminator': prop.isDiscriminator, 'discriminator': prop.isDiscriminator,
'complex': prop._pointer, 'complex': prop._pointer,
@ -103,5 +111,4 @@
</ng-template> </ng-template>
</table> </table>
</ng-template> </ng-template>
</ng-container> </ng-container>

View File

@ -179,6 +179,10 @@ table {
} }
} }
.one-of-selector {
text-align: right;
}
ul, li { ul, li {
margin: 0; margin: 0;
} }

View File

@ -37,6 +37,7 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
_isArray: boolean; _isArray: boolean;
normalizer: SchemaNormalizer; normalizer: SchemaNormalizer;
descendants: DescendantInfo[]; descendants: DescendantInfo[];
activeChoice: number;
constructor( constructor(
specMgr: SpecManager, specMgr: SpecManager,
@ -96,6 +97,11 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
this.selectDescendantByIdx(0); this.selectDescendantByIdx(0);
} }
selectChoice(index) {
if (typeof index === "object") return;
this.activeChoice = index
}
init() { init() {
if (!this.pointer) return; if (!this.pointer) return;
if (!this.absolutePointer) this.absolutePointer = this.pointer; if (!this.absolutePointer) this.absolutePointer = this.pointer;
@ -112,38 +118,51 @@ export class JsonSchema extends BaseSearchableComponent implements OnInit {
this._isArray = this.schema._isArray; this._isArray = this.schema._isArray;
this.absolutePointer += (this._isArray ? '/items' : ''); this.absolutePointer += (this._isArray ? '/items' : '');
this.initDescendants(); this.initDescendants();
this.selectChoice(0);
this.preprocessSchema(); this.preprocessSchema();
} }
preprocessSchema() { preprocessSchema() {
SchemaHelper.preprocess(this.schema, this.normPointer, this.pointer); SchemaHelper.preprocess(this.schema, this.normPointer, this.pointer);
if (!this.schema.isTrivial) { if (!this.schema.isTrivial && !this.schema._wrapped) {
SchemaHelper.preprocessProperties(this.schema, this.normPointer, { SchemaHelper.preprocessProperties(this.schema, this.normPointer, {
childFor: this.childFor, childFor: this.childFor,
discriminator: this.discriminator discriminator: this.discriminator
}); });
} }
this.properties = this.schema._properties || []; if (this.schema._wrapped) {
if (this.isRequestSchema) { this.schema._wrapped.forEach((schema) => {
this.properties = this.properties.filter(prop => !prop.readOnly); SchemaHelper.preprocessProperties(schema, this.normPointer, {
} childFor: this.childFor,
discriminator: this.discriminator
});
if (this.optionsService.options.requiredPropsFirst) { let properties = schema._properties || [];
SchemaHelper.moveRequiredPropsFirst(this.properties, this.schema.required);
}
this._hasSubSchemas = this.properties && this.properties.some( if (this.isRequestSchema) {
propSchema => { properties = properties.filter(prop => !prop.readOnly);
if (propSchema.type === 'array') {
propSchema = propSchema.items;
} }
return (propSchema && propSchema.type === 'object' && propSchema._pointer);
});
if (this.properties.length === 1) { if (this.optionsService.options.requiredPropsFirst) {
this.properties[0].expanded = true; SchemaHelper.moveRequiredPropsFirst(properties, schema.required);
}
this._hasSubSchemas = properties && properties.some(
propSchema => {
if (propSchema.type === 'array') {
propSchema = propSchema.items;
}
return (propSchema && propSchema.type === 'object' && propSchema._pointer);
});
if (properties.length === 1) {
properties[0].expanded = true;
}
schema.displayProperties = properties
})
} }
} }

View File

@ -85,17 +85,33 @@ const injectors = {
}, },
object: { object: {
check: (propertySchema) => { check: (propertySchema) => {
return propertySchema.type === 'object' && (propertySchema.properties || let isObject = propertySchema.type === 'object' && (propertySchema.properties ||
typeof propertySchema.additionalProperties === 'object'); typeof propertySchema.additionalProperties === 'object');
let isChoiceObject = propertySchema.oneOf && propertySchema.oneOf.length > 0 ||
propertySchema.anyOf && propertySchema.anyOf.length > 0
return isObject || isChoiceObject;
}, },
inject: (injectTo, propertySchema = injectTo) => { inject: (injectTo, propertySchema = injectTo) => {
let baseName = propertySchema._pointer && JsonPointer.baseName(propertySchema._pointer);
injectTo._displayType = propertySchema.title || baseName || 'object';
injectTo._widgetType = 'object'; injectTo._widgetType = 'object';
if (propertySchema.type === 'object') {
let baseName = propertySchema._pointer && JsonPointer.baseName(propertySchema._pointer);
injectTo._displayType = propertySchema.title || baseName || 'object';
injectTo._wrapped = [propertySchema];
} else if (propertySchema.oneOf) {
injectTo._displayType = 'oneOf';
injectTo._choiceTitle = 'One of';
injectTo._wrapped = propertySchema.oneOf
} else if (propertySchema.anyOf) {
injectTo._displayType = 'anyOf';
injectTo._choiceTitle = 'Any of';
injectTo._wrapped = propertySchema.anyOf
}
} }
}, },
noType: { noType: {
check: (propertySchema) => !propertySchema.type, check: (propertySchema) => !propertySchema.type && !propertySchema.oneOf && !propertySchema.anyOf,
inject: (injectTo) => { inject: (injectTo) => {
injectTo._displayType = '< anything >'; injectTo._displayType = '< anything >';
injectTo._displayTypeHint = 'This field may contain data of any type'; injectTo._displayTypeHint = 'This field may contain data of any type';
@ -110,7 +126,7 @@ const injectors = {
return (!propertySchema.properties || !Object.keys(propertySchema.properties).length) return (!propertySchema.properties || !Object.keys(propertySchema.properties).length)
&& (typeof propertySchema.additionalProperties !== 'object'); && (typeof propertySchema.additionalProperties !== 'object');
} }
return (propertySchema.type !== 'array') && propertySchema.type; return (propertySchema.type !== 'array' && !propertySchema.oneOf && !propertySchema.anyOf) && propertySchema.type;
}, },
inject: (injectTo, propertySchema = injectTo) => { inject: (injectTo, propertySchema = injectTo) => {
injectTo.isTrivial = true; injectTo.isTrivial = true;

View File

@ -13,6 +13,8 @@ export interface Reference {
export interface Schema { export interface Schema {
properties: any; properties: any;
allOf: any; allOf: any;
oneOf: any;
anyOf: any;
items: any; items: any;
additionalProperties: any; additionalProperties: any;
} }
@ -73,6 +75,16 @@ class SchemaWalker {
SchemaWalker.walkEach(obj.allOf, ptr, visitor); SchemaWalker.walkEach(obj.allOf, ptr, visitor);
} }
if (obj.oneOf) {
let ptr = JsonPointer.join(pointer, ['oneOf']);
SchemaWalker.walkEach(obj.oneOf, ptr, visitor);
}
if (obj.anyOf) {
let ptr = JsonPointer.join(pointer, ['anyOf']);
SchemaWalker.walkEach(obj.anyOf, ptr, visitor);
}
if (obj.items) { if (obj.items) {
let ptr = JsonPointer.join(pointer, ['items']); let ptr = JsonPointer.join(pointer, ['items']);
if (Array.isArray(obj.items)) { if (Array.isArray(obj.items)) {