Merge v1.7.0 into master
This commit is contained in:
parent
fdf14cd101
commit
f10516deb7
21 changed files with 403 additions and 63 deletions
|
@ -1,5 +1,6 @@
|
|||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
|
||||
|
@ -8,6 +9,9 @@ describe('AppComponent', () => {
|
|||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
schemas: [
|
||||
CUSTOM_ELEMENTS_SCHEMA
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -16,17 +20,5 @@ describe('AppComponent', () => {
|
|||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
|
||||
it(`should have as title 'app'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('app');
|
||||
}));
|
||||
|
||||
it('should render title in a h1 tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||
}));
|
||||
|
||||
});
|
||||
|
|
|
@ -13,6 +13,7 @@ import { ProvidersComponent } from './components/providers/providers.component';
|
|||
import { LetDirective } from './directives/let.directive';
|
||||
import { BackendFilterPipe } from './pipes/backend.filter.pipe';
|
||||
import { FrontendFilterPipe } from './pipes/frontend.filter.pipe';
|
||||
import { HumanReadableFilterPipe } from './pipes/humanreadable.filter.pipe';
|
||||
import { KeysPipe } from './pipes/keys.pipe';
|
||||
import { ApiService } from './services/api.service';
|
||||
import { WindowService } from './services/window.service';
|
||||
|
@ -28,6 +29,7 @@ import { WindowService } from './services/window.service';
|
|||
KeysPipe,
|
||||
FrontendFilterPipe,
|
||||
BackendFilterPipe,
|
||||
HumanReadableFilterPipe,
|
||||
LetDirective
|
||||
],
|
||||
imports: [
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BarChartComponent } from './bar-chart.component';
|
||||
import { WindowService } from '../../services/window.service';
|
||||
|
||||
describe('BarChartComponent', () => {
|
||||
let component: BarChartComponent;
|
||||
|
@ -8,7 +9,8 @@ describe('BarChartComponent', () => {
|
|||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ BarChartComponent ]
|
||||
declarations: [ BarChartComponent ],
|
||||
providers: [{provide: WindowService, useInstance: {}}]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
@ -16,10 +18,14 @@ describe('BarChartComponent', () => {
|
|||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BarChartComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should initially go to loading state', () => {
|
||||
expect(component.loading).toBeTruthy()
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -435,6 +435,41 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- details.ratelimit-->
|
||||
<div *ngIf="p.ratelimit">
|
||||
<hr>
|
||||
<div class="section-line">
|
||||
<div class="columns">
|
||||
<div class="column is-3">
|
||||
<h2 class="section-line-header">Rate Limiting</h2>
|
||||
</div>
|
||||
<div class="column is-9">
|
||||
<div class="control">
|
||||
<div class="tags has-addons">
|
||||
<span class="tag is-light">Extractor Function</span>
|
||||
<span class="tag is-info">{{ p.ratelimit.extractorFunc }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table is-fullwidth is-hoverable table-fixed">
|
||||
<thead>
|
||||
<td>Rateset</td>
|
||||
<td>Period</td>
|
||||
<td>Average</td>
|
||||
<td>Burst</td>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let rateset of p.ratelimit.rateset">
|
||||
<td>{{rateset.id}}</td>
|
||||
<td>{{rateset.period | humanreadable}}</td>
|
||||
<td>{{rateset.average}}</td>
|
||||
<td>{{rateset.burst}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
46
webui/src/app/pipes/humanreadable.filter.pipe.spec.ts
Normal file
46
webui/src/app/pipes/humanreadable.filter.pipe.spec.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { HumanReadableFilterPipe } from './humanreadable.filter.pipe';
|
||||
|
||||
describe('HumanReadableFilterPipe', () => {
|
||||
const pipe = new HumanReadableFilterPipe();
|
||||
|
||||
const datatable = [{
|
||||
'given': '180000000000',
|
||||
'expected': '180s'
|
||||
},
|
||||
{
|
||||
'given': '4096.0',
|
||||
'expected': '4096ns'
|
||||
},
|
||||
{
|
||||
'given': '7200000000000',
|
||||
'expected': '120m'
|
||||
},
|
||||
{
|
||||
'given': '1337',
|
||||
'expected': '1337ns'
|
||||
},
|
||||
{
|
||||
'given': 'traefik',
|
||||
'expected': 'traefik',
|
||||
},
|
||||
{
|
||||
'given': '-23',
|
||||
'expected': '-23',
|
||||
},
|
||||
{
|
||||
'given': '0',
|
||||
'expected': '0',
|
||||
},
|
||||
];
|
||||
|
||||
datatable.forEach(item => {
|
||||
it((item.given + ' should be transformed to ' + item.expected ), () => {
|
||||
expect(pipe.transform(item.given)).toEqual(item.expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('create an instance', () => {
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
27
webui/src/app/pipes/humanreadable.filter.pipe.ts
Normal file
27
webui/src/app/pipes/humanreadable.filter.pipe.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
/**
|
||||
* HumanReadableFilterPipe converts a time period in nanoseconds to a human-readable
|
||||
* string.
|
||||
*/
|
||||
@Pipe({name: 'humanreadable'})
|
||||
export class HumanReadableFilterPipe implements PipeTransform {
|
||||
transform(value): any {
|
||||
let result = '';
|
||||
const powerOf10 = Math.floor(Math.log10(value));
|
||||
|
||||
if (powerOf10 > 11) {
|
||||
result = value / (60 * Math.pow(10, 9)) + 'm';
|
||||
} else if (powerOf10 > 9) {
|
||||
result = value / Math.pow(10, 9) + 's';
|
||||
} else if (powerOf10 > 6) {
|
||||
result = value / Math.pow(10, 6) + 'ms';
|
||||
} else if (value > 0) {
|
||||
result = Math.floor(value) + 'ns';
|
||||
} else {
|
||||
result = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -67,6 +67,9 @@ export class ApiService {
|
|||
frontend.headers.customResponseHeaders = this.toHeaderArray(frontend.headers.customResponseHeaders);
|
||||
frontend.headers.sslProxyHeaders = this.toHeaderArray(frontend.headers.sslProxyHeaders);
|
||||
}
|
||||
if (frontend.ratelimit && frontend.ratelimit.rateset) {
|
||||
frontend.ratelimit.rateset = this.toArray(frontend.ratelimit.rateset, 'id');
|
||||
}
|
||||
return frontend;
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue