mirror of
https://github.com/Redocly/redoc.git
synced 2025-02-07 13:30:33 +03:00
Merge branch 'master' into releases
This commit is contained in:
commit
132974acc0
|
@ -12,7 +12,7 @@ gulp.task('test-server', function (done) {
|
|||
baseDir: './tests/e2e',
|
||||
routes: {
|
||||
'/dist': './dist',
|
||||
'/swagger.json': './demo/swagger.json'
|
||||
'/swagger.yml': './demo/swagger.yml'
|
||||
},
|
||||
}
|
||||
}, done);
|
||||
|
|
|
@ -169,6 +169,21 @@
|
|||
description: "Pet not found"
|
||||
405:
|
||||
description: "Validation exception"
|
||||
x-code-samples:
|
||||
-
|
||||
lang: PHP
|
||||
source: |-
|
||||
$form = new \PetStore\Entities\Pet();
|
||||
$form->setPetId(1);
|
||||
$form->setPetType("Dog");
|
||||
$form->setName("Rex");
|
||||
// set other fields
|
||||
|
||||
try {
|
||||
$pet = $client->pets()->update($form);
|
||||
} catch (UnprocessableEntityException $e) {
|
||||
var_dump($e->getErrors());
|
||||
}
|
||||
security:
|
||||
-
|
||||
petstore_auth:
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
# ReDoc vendor extensions
|
||||
ReDoc makes use of the following [vendor extensions](http://swagger.io/specification/#vendorExtensions)
|
||||
|
||||
### <a name="infoObject"></a> [Info Object](http://swagger.io/specification/#infoObject) vendor extensions
|
||||
### <a name="infoObject"></a>[Info Object](http://swagger.io/specification/#infoObject) vendor extensions
|
||||
|
||||
#### <a name="x-logo"></a> x-logo
|
||||
| Field Name | Type | Description
|
||||
| :------------- | :------: |
|
||||
| x-logo | [Logo Object](#logoObject) | The information about API logo
|
||||
|
||||
##### Usage in Redoc
|
||||
| Field Name | Type | Description |
|
||||
| :------------- | :-----------: | :---------- |
|
||||
| x-logo | [Logo Object](#logoObject) | The information about API logo |
|
||||
|
||||
###### Usage in Redoc
|
||||
`x-logo` is used to specify API logo. The corresponding image are displayed just above side-menu.
|
||||
|
||||
#### <a name="logoObject"></a> Logo Object
|
||||
#### <a name="logoObject"></a>Logo Object
|
||||
The information about API logo
|
||||
##### Fixed fields
|
||||
| Field Name | Type | Description
|
||||
| :---------- | :------: |
|
||||
| url | string | The URL pointing to the spec logo. MUST be in the format of a URL
|
||||
| backgroundColor | string | background color to be used. MUST be in [CSS color syntax](https://developer.mozilla.org/en/docs/Web/CSS/color)
|
||||
###### Fixed fields
|
||||
| Field Name | Type | Description |
|
||||
| :-------------- | :------: | :---------- |
|
||||
| url | string | The URL pointing to the spec logo. MUST be in the format of a URL
|
||||
| backgroundColor | string | background color to be used. MUST be in [CSS color syntax](https://developer.mozilla.org/en/docs/Web/CSS/color) |
|
||||
|
||||
|
||||
##### x-logo example
|
||||
```yaml
|
||||
###### x-logo example
|
||||
json
|
||||
```json
|
||||
{
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
|
@ -33,15 +35,14 @@ The information about API logo
|
|||
}
|
||||
}
|
||||
```
|
||||
yaml
|
||||
```yaml
|
||||
{
|
||||
info:
|
||||
version: "1.0.0"
|
||||
title: "Swagger Petstore"
|
||||
x-logo:
|
||||
url: "https://rebilly.github.io/ReDoc/petstore-logo.png"
|
||||
backgroundColor: "white"
|
||||
}
|
||||
info:
|
||||
version: "1.0.0"
|
||||
title: "Swagger Petstore"
|
||||
x-logo:
|
||||
url: "https://rebilly.github.io/ReDoc/petstore-logo.png"
|
||||
backgroundColor: "white"
|
||||
```
|
||||
|
||||
|
||||
|
@ -49,15 +50,16 @@ The information about API logo
|
|||
### [Tag object](http://swagger.io/specification/#tagObject) vendor extensions
|
||||
|
||||
#### <a name="x-traitTag"></a> x-traitTag
|
||||
| Field Name | Type | Description
|
||||
| :------------- | :------: |
|
||||
| x-traitTag | boolean | In Swagger two operations can have multiply tags. This property distinguish between tags that are used to group operations (default) from tags that are used to mark operation with certain trait (`true` value)
|
||||
| Field Name | Type | Description |
|
||||
| :------------- | :------: | :---------- |
|
||||
| x-traitTag | boolean | In Swagger two operations can have multiply tags. This property distinguish between tags that are used to group operations (default) from tags that are used to mark operation with certain trait (`true` value) |
|
||||
|
||||
##### Usage in Redoc
|
||||
###### Usage in Redoc
|
||||
Tags that have `x-traitTag` set to `true` are listed in side-menu but don't have any subitems (operations). Tag `description` is rendered as well.
|
||||
This is useful for handling out common things like Pagination, Rate-Limits, etc.
|
||||
|
||||
##### x-traitTag example
|
||||
###### x-traitTag example
|
||||
json
|
||||
```json
|
||||
{
|
||||
"name": "Pagination",
|
||||
|
@ -65,6 +67,7 @@ This is useful for handling out common things like Pagination, Rate-Limits, etc.
|
|||
"x-traitTag": true
|
||||
}
|
||||
```
|
||||
yaml
|
||||
```yaml
|
||||
name: Pagination
|
||||
description: Pagination description (can use markdown syntax)
|
||||
|
@ -74,32 +77,32 @@ x-traitTag: true
|
|||
### [Operation Object](http://swagger.io/specification/#operationObject) vendor extensions
|
||||
|
||||
#### <a name="x-code-samples"></a> x-code-samples
|
||||
| Field Name | Type | Description
|
||||
| :------------- | :------: |
|
||||
| x-code-samples | [[Code Sample Object](#codeSampleObject)] | A list of code samples associated with operation
|
||||
| Field Name | Type | Description |
|
||||
| :------------- | :------: | :---------- |
|
||||
| x-code-samples | [ [Code Sample Object](#codeSampleObject) ] | A list of code samples associated with operation |
|
||||
|
||||
##### Usage in ReDoc
|
||||
x-code-samples are rendered on the right panel of ReDoc
|
||||
###### Usage in ReDoc
|
||||
`x-code-samples` are rendered on the right panel of ReDoc
|
||||
|
||||
#### <a name="codeSampleObject"></a> Code Sample Object
|
||||
#### <a name="codeSampleObject"></a>Code Sample Object
|
||||
Operation code sample
|
||||
##### Fixed fields
|
||||
| Field Name | Type | Description
|
||||
| :---------- | :------: | :-----------
|
||||
| lang | string | Code sample language. Value should be one of the following [list](https://github.com/github/linguist/blob/master/lib/linguist/popular.yml)
|
||||
| source | string | Code sample source code
|
||||
###### Fixed fields
|
||||
| Field Name | Type | Description |
|
||||
| :---------- | :------: | :----------- |
|
||||
| lang | string | Code sample language. Value should be one of the following [list](https://github.com/github/linguist/blob/master/lib/linguist/popular.yml) |
|
||||
| source | string | Code sample source code |
|
||||
|
||||
|
||||
##### Code Sample Object example
|
||||
```yaml
|
||||
###### Code Sample Object example
|
||||
json
|
||||
```json
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "console.log('Hello World');"
|
||||
}
|
||||
```
|
||||
yaml
|
||||
```yaml
|
||||
{
|
||||
lang: JavaScript
|
||||
source: console.log('Hello World');
|
||||
}
|
||||
lang: JavaScript
|
||||
source: console.log('Hello World');
|
||||
```
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
import {Component, View} from 'angular2/core';
|
||||
import {Component, View, EventEmitter} from 'angular2/core';
|
||||
import {CORE_DIRECTIVES} from 'angular2/common';
|
||||
|
||||
@Component({
|
||||
selector: 'tabs'
|
||||
selector: 'tabs',
|
||||
events: ['change']
|
||||
})
|
||||
@View({
|
||||
template: `
|
||||
|
@ -20,13 +21,34 @@ import {CORE_DIRECTIVES} from 'angular2/common';
|
|||
export class Tabs {
|
||||
constructor() {
|
||||
this.tabs = [];
|
||||
this.change = new EventEmitter();
|
||||
}
|
||||
|
||||
selectTab(tab) {
|
||||
selectTab(tab, notify = true) {
|
||||
if (tab.active) return;
|
||||
this.tabs.forEach((tab) => {
|
||||
tab.active = false;
|
||||
});
|
||||
tab.active = true;
|
||||
notify && this.change.next(tab.tabTitle);
|
||||
}
|
||||
|
||||
selectyByTitle(tabTitle, notify = false) {
|
||||
let prevActive;
|
||||
let newActive;
|
||||
this.tabs.forEach((tab) => {
|
||||
if (tab.active) prevActive = tab;
|
||||
tab.active = false;
|
||||
if (tab.tabTitle === tabTitle) {
|
||||
newActive = tab;
|
||||
}
|
||||
});
|
||||
if (newActive) {
|
||||
newActive.active = true;
|
||||
} else {
|
||||
prevActive.active = true;
|
||||
}
|
||||
notify && this.change.next(tabTitle);
|
||||
}
|
||||
|
||||
addTab(tab) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
import { getChildDebugElement, getChildDebugElementAll, mouseclick } from 'tests/helpers';
|
||||
import { getChildDebugElement, getChildDebugElementAll } from 'tests/helpers';
|
||||
import {Component, View} from 'angular2/core';
|
||||
|
||||
import {
|
||||
|
@ -16,9 +16,10 @@ describe('Common components', () => {
|
|||
describe('Tabs Component', () => {
|
||||
let builder;
|
||||
let component;
|
||||
let nativeElement;
|
||||
let childDebugEls;
|
||||
let debugEl;
|
||||
let fixture;
|
||||
let hostComponent;
|
||||
|
||||
beforeEach(inject([TestComponentBuilder], (tcb) => {
|
||||
builder = tcb;
|
||||
|
@ -26,10 +27,10 @@ describe('Common components', () => {
|
|||
beforeEach((done) => {
|
||||
builder.createAsync(TestApp).then(_fixture => {
|
||||
fixture = _fixture;
|
||||
let debugEl = getChildDebugElement(fixture.debugElement, 'tabs');
|
||||
hostComponent = fixture.debugElement.componentInstance;
|
||||
debugEl = getChildDebugElement(fixture.debugElement, 'tabs');
|
||||
childDebugEls = getChildDebugElementAll(debugEl, 'tab');
|
||||
component = debugEl.componentInstance;
|
||||
nativeElement = debugEl.nativeElement;
|
||||
done();
|
||||
}, err => done.fail(err));
|
||||
});
|
||||
|
@ -54,13 +55,82 @@ describe('Common components', () => {
|
|||
|
||||
it('should change active tab on click', () => {
|
||||
fixture.detectChanges();
|
||||
let headerEls = nativeElement.querySelectorAll('li');
|
||||
//let headerEls = nativeElement.querySelectorAll('li');
|
||||
let tabs = childDebugEls.map(debugEl => debugEl.componentInstance);
|
||||
let [tab1, tab2] = tabs;
|
||||
|
||||
mouseclick(headerEls[0]);
|
||||
tab1.active.should.be.false;
|
||||
tab2.active.should.be.true;
|
||||
let tabsInst = debugEl.componentInstance;
|
||||
tabsInst.selectTab(tab2);
|
||||
tab1.active.should.be.false();
|
||||
tab2.active.should.be.true();
|
||||
});
|
||||
|
||||
it('should change tab by title and not emit Event', (done) => {
|
||||
fixture.detectChanges();
|
||||
let tabs = childDebugEls.map(debugEl => debugEl.componentInstance);
|
||||
let [tab1, tab2] = tabs;
|
||||
let tab2Title = 'Tab2';
|
||||
|
||||
let tabsInst = debugEl.componentInstance;
|
||||
tabsInst.selectyByTitle(tab2Title);
|
||||
tab1.active.should.be.false();
|
||||
tab2.active.should.be.true();
|
||||
|
||||
setTimeout(() => {
|
||||
hostComponent.eventLog.should.be.deepEqual([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should emit event on tab Change', (done) => {
|
||||
fixture.detectChanges();
|
||||
let tabs = childDebugEls.map(debugEl => debugEl.componentInstance);
|
||||
let tab2 = tabs[1];
|
||||
let tabsInst = debugEl.componentInstance;
|
||||
tabsInst.selectTab(tab2, true);
|
||||
|
||||
setTimeout(() => {
|
||||
hostComponent.eventLog.should.be.deepEqual(['Tab2']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit event on tab change by Title with notify true', (done) => {
|
||||
fixture.detectChanges();
|
||||
let tab2Title = 'Tab2';
|
||||
|
||||
let tabsInst = debugEl.componentInstance;
|
||||
tabsInst.selectyByTitle(tab2Title, true);
|
||||
|
||||
setTimeout(() => {
|
||||
hostComponent.eventLog.should.be.deepEqual(['Tab2']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not emit event on tab change with notify false', (done) => {
|
||||
fixture.detectChanges();
|
||||
let tabs = childDebugEls.map(debugEl => debugEl.componentInstance);
|
||||
let tab2 = tabs[1];
|
||||
let tabsInst = debugEl.componentInstance;
|
||||
tabsInst.selectTab(tab2, false);
|
||||
|
||||
setTimeout(() => {
|
||||
hostComponent.eventLog.should.be.deepEqual([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should leave current tab active if selectyByTitle non existing title', () => {
|
||||
fixture.detectChanges();
|
||||
let tabs = childDebugEls.map(debugEl => debugEl.componentInstance);
|
||||
let [tab1, tab2] = tabs;
|
||||
|
||||
let tabsInst = debugEl.componentInstance;
|
||||
tabsInst.selectyByTitle('badTitle');
|
||||
tab1.active.should.be.true();
|
||||
tab2.active.should.be.false();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -71,10 +141,16 @@ describe('Common components', () => {
|
|||
@View({
|
||||
directives: [Tabs, Tab],
|
||||
template:
|
||||
`<tabs>
|
||||
`<tabs (change)="onEvent($event)">
|
||||
<tab tabTitle="Tab1" tabStatus="test">Test</tab>
|
||||
<tab tabTitle="Tab2" tabStatus="test">Test</tab>
|
||||
</tabs>`
|
||||
})
|
||||
class TestApp {
|
||||
constructor() {
|
||||
this.eventLog = [];
|
||||
}
|
||||
onEvent(event) {
|
||||
this.eventLog.push(event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<header *ngIf="data.bodySchemaPtr || data.samples.length"> Request samples </header>
|
||||
<schema-sample *ngIf="!data.samples.length" [pointer]="data.bodySchemaPtr"> </schema-sample>
|
||||
<tabs *ngIf="data.samples.length">
|
||||
<tabs *ngIf="data.samples.length" (change)=changeLangNotify($event)>
|
||||
<tab tabTitle="JSON">
|
||||
<schema-sample [pointer]="data.bodySchemaPtr"> </schema-sample>
|
||||
</tab>
|
||||
|
|
|
@ -6,17 +6,38 @@ import {Tabs, Tab} from '../../common/components/Tabs/tabs';
|
|||
import SchemaSample from '../SchemaSample/schema-sample';
|
||||
import {PrismPipe} from '../../utils/pipes';
|
||||
|
||||
import {ViewChildren, QueryList, ChangeDetectorRef, ChangeDetectionStrategy} from 'angular2/core';
|
||||
import {redocEvents} from '../../events';
|
||||
|
||||
@RedocComponent({
|
||||
selector: 'request-samples',
|
||||
templateUrl: './lib/components/RequestSamples/request-samples.html',
|
||||
styleUrls: ['./lib/components/RequestSamples/request-samples.css'],
|
||||
directives: [SchemaSample, Tabs, Tab],
|
||||
inputs: ['bodySchemaPtr'],
|
||||
pipes: [PrismPipe]
|
||||
pipes: [PrismPipe],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export default class RequestSamples extends BaseComponent {
|
||||
constructor(schemaMgr) {
|
||||
constructor(schemaMgr, tabs, changeDetector) {
|
||||
super(schemaMgr);
|
||||
tabs.changes.subscribe(_ => {
|
||||
this.tabs = tabs.first;
|
||||
this.subscribeForEvents(_);
|
||||
});
|
||||
this.changeDetector = changeDetector;
|
||||
}
|
||||
|
||||
changeLangNotify(lang) {
|
||||
redocEvents.samplesLanguageChanged.next(lang);
|
||||
}
|
||||
|
||||
subscribeForEvents() {
|
||||
if (!this.tabs) return;
|
||||
redocEvents.samplesLanguageChanged.subscribe((sampleLang) => {
|
||||
this.tabs.selectyByTitle(sampleLang);
|
||||
this.changeDetector.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
prepareModel() {
|
||||
|
@ -25,3 +46,5 @@ export default class RequestSamples extends BaseComponent {
|
|||
this.data.samples = this.componentSchema['x-code-samples'] || [];
|
||||
}
|
||||
}
|
||||
|
||||
RequestSamples.parameters = RequestSamples.parameters.concat([ [new ViewChildren(Tabs), QueryList], [ChangeDetectorRef] ]);
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
import {EventEmitter} from 'angular2/core';
|
||||
|
||||
var bootsrEmmiter = new EventEmitter();
|
||||
var langChanged = new EventEmitter();
|
||||
export var redocEvents = {
|
||||
bootstrapped: bootsrEmmiter
|
||||
bootstrapped: bootsrEmmiter,
|
||||
samplesLanguageChanged: langChanged
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "redoc",
|
||||
"description": "Swagger-generated API Reference Documentation",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/Rebilly/ReDoc"
|
||||
|
@ -10,7 +10,7 @@
|
|||
"scripts": {
|
||||
"test": "gulp lint && ./build/run_tests.sh",
|
||||
"prepublish": "gulp build",
|
||||
"postinstall": "jspm install",
|
||||
"postinstall": "npm install jspm && jspm install",
|
||||
"start": "gulp serve",
|
||||
"build-dist": "gulp build",
|
||||
"branch-release": "git reset --hard && branch-release",
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<script>
|
||||
window.redocError = null;
|
||||
/* init redoc */
|
||||
var url = window.location.search.substr(5) || 'swagger.json';
|
||||
var url = window.location.search.substr(5) || 'swagger.yml';
|
||||
Redoc.init(decodeURIComponent(url), {disableLazySchemas: true}).then(function() {}, function(err) {
|
||||
window.redocError = err;
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user