mirror of
https://github.com/Redocly/redoc.git
synced 2025-07-12 17:22:29 +03:00
Synchronize code samples tabs #20
This commit is contained in:
parent
6a5823e5be
commit
620d206ac8
|
@ -169,6 +169,41 @@
|
||||||
description: "Pet not found"
|
description: "Pet not found"
|
||||||
405:
|
405:
|
||||||
description: "Validation exception"
|
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());
|
||||||
|
}
|
||||||
|
-
|
||||||
|
lang: C#
|
||||||
|
source: |-
|
||||||
|
PetStore.v1.Pet pet = new PetStore.v1.Pet();
|
||||||
|
pet.setApiKey("your api key");
|
||||||
|
pet.petType = PetStore.v1.Pet.TYPE_DOG;
|
||||||
|
pet.id = 1;
|
||||||
|
pet.name = "Rex";
|
||||||
|
// set other fields
|
||||||
|
|
||||||
|
PetStoreResponse response = pet.update();
|
||||||
|
if (response.statusCode == HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
// Successfully updated
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something wrong -- check response for errors
|
||||||
|
Console.WriteLine(response.getRawResponse());
|
||||||
|
}
|
||||||
security:
|
security:
|
||||||
-
|
-
|
||||||
petstore_auth:
|
petstore_auth:
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {Component, View} from 'angular2/core';
|
import {Component, View, EventEmitter} from 'angular2/core';
|
||||||
import {CORE_DIRECTIVES} from 'angular2/common';
|
import {CORE_DIRECTIVES} from 'angular2/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tabs'
|
selector: 'tabs',
|
||||||
|
events: ['change']
|
||||||
})
|
})
|
||||||
@View({
|
@View({
|
||||||
template: `
|
template: `
|
||||||
|
@ -20,13 +21,34 @@ import {CORE_DIRECTIVES} from 'angular2/common';
|
||||||
export class Tabs {
|
export class Tabs {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.tabs = [];
|
this.tabs = [];
|
||||||
|
this.change = new EventEmitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectTab(tab) {
|
selectTab(tab, notify = true) {
|
||||||
|
if (tab.active) return;
|
||||||
this.tabs.forEach((tab) => {
|
this.tabs.forEach((tab) => {
|
||||||
tab.active = false;
|
tab.active = false;
|
||||||
});
|
});
|
||||||
tab.active = true;
|
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) {
|
addTab(tab) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement, getChildDebugElementAll, mouseclick } from 'tests/helpers';
|
import { getChildDebugElement, getChildDebugElementAll } from 'tests/helpers';
|
||||||
import {Component, View} from 'angular2/core';
|
import {Component, View} from 'angular2/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -16,9 +16,10 @@ describe('Common components', () => {
|
||||||
describe('Tabs Component', () => {
|
describe('Tabs Component', () => {
|
||||||
let builder;
|
let builder;
|
||||||
let component;
|
let component;
|
||||||
let nativeElement;
|
|
||||||
let childDebugEls;
|
let childDebugEls;
|
||||||
|
let debugEl;
|
||||||
let fixture;
|
let fixture;
|
||||||
|
let hostComponent;
|
||||||
|
|
||||||
beforeEach(inject([TestComponentBuilder], (tcb) => {
|
beforeEach(inject([TestComponentBuilder], (tcb) => {
|
||||||
builder = tcb;
|
builder = tcb;
|
||||||
|
@ -26,10 +27,10 @@ describe('Common components', () => {
|
||||||
beforeEach((done) => {
|
beforeEach((done) => {
|
||||||
builder.createAsync(TestApp).then(_fixture => {
|
builder.createAsync(TestApp).then(_fixture => {
|
||||||
fixture = _fixture;
|
fixture = _fixture;
|
||||||
let debugEl = getChildDebugElement(fixture.debugElement, 'tabs');
|
hostComponent = fixture.debugElement.componentInstance;
|
||||||
|
debugEl = getChildDebugElement(fixture.debugElement, 'tabs');
|
||||||
childDebugEls = getChildDebugElementAll(debugEl, 'tab');
|
childDebugEls = getChildDebugElementAll(debugEl, 'tab');
|
||||||
component = debugEl.componentInstance;
|
component = debugEl.componentInstance;
|
||||||
nativeElement = debugEl.nativeElement;
|
|
||||||
done();
|
done();
|
||||||
}, err => done.fail(err));
|
}, err => done.fail(err));
|
||||||
});
|
});
|
||||||
|
@ -54,13 +55,82 @@ describe('Common components', () => {
|
||||||
|
|
||||||
it('should change active tab on click', () => {
|
it('should change active tab on click', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let headerEls = nativeElement.querySelectorAll('li');
|
//let headerEls = nativeElement.querySelectorAll('li');
|
||||||
let tabs = childDebugEls.map(debugEl => debugEl.componentInstance);
|
let tabs = childDebugEls.map(debugEl => debugEl.componentInstance);
|
||||||
let [tab1, tab2] = tabs;
|
let [tab1, tab2] = tabs;
|
||||||
|
|
||||||
mouseclick(headerEls[0]);
|
let tabsInst = debugEl.componentInstance;
|
||||||
tab1.active.should.be.false;
|
tabsInst.selectTab(tab2);
|
||||||
tab2.active.should.be.true;
|
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({
|
@View({
|
||||||
directives: [Tabs, Tab],
|
directives: [Tabs, Tab],
|
||||||
template:
|
template:
|
||||||
`<tabs>
|
`<tabs (change)="onEvent($event)">
|
||||||
<tab tabTitle="Tab1" tabStatus="test">Test</tab>
|
<tab tabTitle="Tab1" tabStatus="test">Test</tab>
|
||||||
<tab tabTitle="Tab2" tabStatus="test">Test</tab>
|
<tab tabTitle="Tab2" tabStatus="test">Test</tab>
|
||||||
</tabs>`
|
</tabs>`
|
||||||
})
|
})
|
||||||
class TestApp {
|
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>
|
<header *ngIf="data.bodySchemaPtr || data.samples.length"> Request samples </header>
|
||||||
<schema-sample *ngIf="!data.samples.length" [pointer]="data.bodySchemaPtr"> </schema-sample>
|
<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">
|
<tab tabTitle="JSON">
|
||||||
<schema-sample [pointer]="data.bodySchemaPtr"> </schema-sample>
|
<schema-sample [pointer]="data.bodySchemaPtr"> </schema-sample>
|
||||||
</tab>
|
</tab>
|
||||||
|
|
|
@ -6,17 +6,38 @@ import {Tabs, Tab} from '../../common/components/Tabs/tabs';
|
||||||
import SchemaSample from '../SchemaSample/schema-sample';
|
import SchemaSample from '../SchemaSample/schema-sample';
|
||||||
import {PrismPipe} from '../../utils/pipes';
|
import {PrismPipe} from '../../utils/pipes';
|
||||||
|
|
||||||
|
import {ViewChildren, QueryList, ChangeDetectorRef, ChangeDetectionStrategy} from 'angular2/core';
|
||||||
|
import {redocEvents} from '../../events';
|
||||||
|
|
||||||
@RedocComponent({
|
@RedocComponent({
|
||||||
selector: 'request-samples',
|
selector: 'request-samples',
|
||||||
templateUrl: './lib/components/RequestSamples/request-samples.html',
|
templateUrl: './lib/components/RequestSamples/request-samples.html',
|
||||||
styleUrls: ['./lib/components/RequestSamples/request-samples.css'],
|
styleUrls: ['./lib/components/RequestSamples/request-samples.css'],
|
||||||
directives: [SchemaSample, Tabs, Tab],
|
directives: [SchemaSample, Tabs, Tab],
|
||||||
inputs: ['bodySchemaPtr'],
|
inputs: ['bodySchemaPtr'],
|
||||||
pipes: [PrismPipe]
|
pipes: [PrismPipe],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export default class RequestSamples extends BaseComponent {
|
export default class RequestSamples extends BaseComponent {
|
||||||
constructor(schemaMgr) {
|
constructor(schemaMgr, tabs, changeDetector) {
|
||||||
super(schemaMgr);
|
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() {
|
prepareModel() {
|
||||||
|
@ -25,3 +46,5 @@ export default class RequestSamples extends BaseComponent {
|
||||||
this.data.samples = this.componentSchema['x-code-samples'] || [];
|
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';
|
import {EventEmitter} from 'angular2/core';
|
||||||
|
|
||||||
var bootsrEmmiter = new EventEmitter();
|
var bootsrEmmiter = new EventEmitter();
|
||||||
|
var langChanged = new EventEmitter();
|
||||||
export var redocEvents = {
|
export var redocEvents = {
|
||||||
bootstrapped: bootsrEmmiter
|
bootstrapped: bootsrEmmiter,
|
||||||
|
samplesLanguageChanged: langChanged
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user