--- /dev/null
+<tabset *ngIf="selectedItem">
+ <tab i18n-heading
+ heading="Details">
+ <div class="row">
+ <div class="col-sm-6">
+ <fieldset>
+ <legend i18n>Ranks</legend>
+
+ <cd-table [data]="ranks.data"
+ [columns]="ranks.columns"
+ (fetchData)="refresh()"
+ [toolHeader]="false">
+ </cd-table>
+ </fieldset>
+
+ <cd-table-key-value [data]="standbys">
+ </cd-table-key-value>
+ </div>
+
+ <div class="col-sm-6">
+ <fieldset>
+ <legend i18n>Pools</legend>
+
+ <cd-table [data]="pools.data"
+ [columns]="pools.columns"
+ [toolHeader]="false">
+ </cd-table>
+
+ </fieldset>
+ </div>
+ </div>
+
+ <div class="row"
+ *ngFor="let mdsCounter of objectValues(mdsCounters); trackBy: trackByFn">
+ <div class="cold-md-12">
+ <cd-cephfs-chart [mdsCounter]="mdsCounter"></cd-cephfs-chart>
+ </div>
+ </div>
+
+ <!-- templates -->
+ <ng-template #poolUsageTpl
+ let-row="row">
+ <cd-usage-bar [totalBytes]="row.size"
+ [usedBytes]="row.used"></cd-usage-bar>
+ </ng-template>
+
+ <ng-template #activityTmpl
+ let-row="row"
+ let-value="value">
+ {{ row.state === 'standby-replay' ? 'Evts' : 'Reqs' }}: {{ value | dimless }} /s
+ </ng-template>
+ </tab>
+ <tab i18n-heading
+ heading="Clients: {{ clientCount }}"
+ (select)="clientsSelect=true"
+ (deselect)="clientsSelect=false">
+ <cd-clients [id]="id"
+ *ngIf="clientsSelect"></cd-clients>
+ </tab>
+</tabset>
--- /dev/null
+.progress {
+ margin-bottom: 0px;
+}
--- /dev/null
+import { Component, Input } from '@angular/core';
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+
+import { ChartsModule } from 'ng2-charts/ng2-charts';
+import { BsDropdownModule, ProgressbarModule, TabsModule } from 'ngx-bootstrap';
+import { Observable } from 'rxjs/Observable';
+
+import { CephfsService } from '../../../shared/api/cephfs.service';
+import { SharedModule } from '../../../shared/shared.module';
+import { CephfsChartComponent } from '../cephfs-chart/cephfs-chart.component';
+import { ClientsComponent } from '../clients/clients.component';
+import { CephfsDetailComponent } from './cephfs-detail.component';
+
+@Component({ selector: 'cd-cephfs-chart', template: '' })
+class CephfsChartStubComponent {
+ @Input() mdsCounter: any;
+}
+
+@Component({ selector: 'cd-clients', template: '' })
+class ClientsStubComponent {
+ @Input() mdsCounter: any;
+}
+
+describe('CephfsDetailComponent', () => {
+ let component: CephfsDetailComponent;
+ let fixture: ComponentFixture<CephfsDetailComponent>;
+
+ const fakeFilesystemService = {
+ getCephfs: (id) => {
+ return Observable.create((observer) => {
+ return () => console.log('disposed');
+ });
+ },
+ getMdsCounters: (id) => {
+ return Observable.create((observer) => {
+ return () => console.log('disposed');
+ });
+ }
+ };
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ SharedModule,
+ ChartsModule,
+ RouterTestingModule,
+ BsDropdownModule.forRoot(),
+ ProgressbarModule.forRoot(),
+ TabsModule.forRoot()
+ ],
+ declarations: [CephfsDetailComponent, CephfsChartStubComponent, ClientsStubComponent],
+ providers: [{ provide: CephfsService, useValue: fakeFilesystemService }]
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CephfsDetailComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
--- /dev/null
+import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
+
+import * as _ from 'lodash';
+
+import { CephfsService } from '../../../shared/api/cephfs.service';
+import { CdTableSelection } from '../../../shared/models/cd-table-selection';
+import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
+import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
+
+@Component({
+ selector: 'cd-cephfs-detail',
+ templateUrl: './cephfs-detail.component.html',
+ styleUrls: ['./cephfs-detail.component.scss']
+})
+export class CephfsDetailComponent implements OnChanges, OnInit {
+ @ViewChild('poolUsageTpl') poolUsageTpl: TemplateRef<any>;
+ @ViewChild('activityTmpl') activityTmpl: TemplateRef<any>;
+
+ @Input() selection: CdTableSelection;
+
+ selectedItem: any;
+
+ id: number;
+ name: string;
+ ranks: any;
+ pools: any;
+ standbys = [];
+ clientCount: number;
+ mdsCounters = {};
+
+ objectValues = Object.values;
+ clientsSelect = false;
+
+ constructor(
+ private cephfsService: CephfsService,
+ private dimlessBinary: DimlessBinaryPipe,
+ private dimless: DimlessPipe
+ ) {}
+
+ ngOnChanges() {
+ if (this.selection.hasSelection) {
+ this.selectedItem = this.selection.first();
+
+ if (this.id !== this.selectedItem.id) {
+ this.id = this.selectedItem.id;
+ this.ranks.data = [];
+ this.pools.data = [];
+ this.standbys = [];
+ this.mdsCounters = {};
+ }
+ }
+ }
+
+ ngOnInit() {
+ this.ranks = {
+ columns: [
+ { prop: 'rank' },
+ { prop: 'state' },
+ { prop: 'mds', name: 'Daemon' },
+ { prop: 'activity', cellTemplate: this.activityTmpl },
+ { prop: 'dns', name: 'Dentries', pipe: this.dimless },
+ { prop: 'inos', name: 'Inodes', pipe: this.dimless }
+ ],
+ data: []
+ };
+
+ this.pools = {
+ columns: [
+ { prop: 'pool' },
+ { prop: 'type' },
+ { prop: 'size', pipe: this.dimlessBinary },
+ {
+ name: 'Usage',
+ cellTemplate: this.poolUsageTpl,
+ comparator: (valueA, valueB, rowA, rowB, sortDirection) => {
+ const valA = rowA.used / rowA.avail;
+ const valB = rowB.used / rowB.avail;
+
+ if (valA === valB) {
+ return 0;
+ }
+
+ if (valA > valB) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+ }
+ ],
+ data: []
+ };
+ }
+
+ refresh() {
+ this.cephfsService.getCephfs(this.id).subscribe((data: any) => {
+ this.ranks.data = data.cephfs.ranks;
+ this.pools.data = data.cephfs.pools;
+ this.pools.data.forEach((pool) => {
+ pool.size = pool.used + pool.avail;
+ });
+ this.standbys = [
+ {
+ key: 'Standby daemons',
+ value: data.standbys.map((value) => value.name).join(', ')
+ }
+ ];
+ this.name = data.cephfs.name;
+ this.clientCount = data.cephfs.client_count;
+ });
+
+ this.cephfsService.getMdsCounters(this.id).subscribe((data) => {
+ _.each(this.mdsCounters, (value, key) => {
+ if (data[key] === undefined) {
+ delete this.mdsCounters[key];
+ }
+ });
+
+ _.each(data, (mdsData: any, mdsName) => {
+ mdsData.name = mdsName;
+ this.mdsCounters[mdsName] = mdsData;
+ });
+ });
+ }
+
+ trackByFn(index, item) {
+ return item.name;
+ }
+}
forceIdentifier="true"
selectionType="single"
(updateSelection)="updateSelection($event)">
- <cd-cephfs cdTableDetail
+ <cd-cephfs-detail cdTableDetail
[selection]="selection">
- </cd-cephfs>
+ </cd-cephfs-detail>
</cd-table>
import { SharedModule } from '../../../shared/shared.module';
import { CephfsListComponent } from './cephfs-list.component';
-@Component({ selector: 'cd-cephfs', template: '' })
-class CephfsStubComponent {
+@Component({ selector: 'cd-cephfs-detail', template: '' })
+class CephfsDetailStubComponent {
@Input() selection: CdTableSelection;
}
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [SharedModule],
- declarations: [CephfsListComponent, CephfsStubComponent],
+ declarations: [CephfsListComponent, CephfsDetailStubComponent],
providers: [{ provide: CephfsService, useValue: fakeService }]
}).compileComponents();
}));
import { AppRoutingModule } from '../../app-routing.module';
import { SharedModule } from '../../shared/shared.module';
import { CephfsChartComponent } from './cephfs-chart/cephfs-chart.component';
+import { CephfsDetailComponent } from './cephfs-detail/cephfs-detail.component';
import { CephfsListComponent } from './cephfs-list/cephfs-list.component';
-import { CephfsComponent } from './cephfs/cephfs.component';
import { ClientsComponent } from './clients/clients.component';
@NgModule({
ProgressbarModule.forRoot(),
TabsModule.forRoot()
],
- declarations: [CephfsComponent, ClientsComponent, CephfsChartComponent, CephfsListComponent]
+ declarations: [CephfsDetailComponent, ClientsComponent, CephfsChartComponent, CephfsListComponent]
})
export class CephfsModule {}
+++ /dev/null
-<tabset *ngIf="selectedItem">
- <tab i18n-heading
- heading="Details">
- <div class="row">
- <div class="col-sm-6">
- <fieldset>
- <legend i18n>Ranks</legend>
-
- <cd-table [data]="ranks.data"
- [columns]="ranks.columns"
- (fetchData)="refresh()"
- [toolHeader]="false">
- </cd-table>
- </fieldset>
-
- <cd-table-key-value [data]="standbys">
- </cd-table-key-value>
- </div>
-
- <div class="col-sm-6">
- <fieldset>
- <legend i18n>Pools</legend>
-
- <cd-table [data]="pools.data"
- [columns]="pools.columns"
- [toolHeader]="false">
- </cd-table>
-
- </fieldset>
- </div>
- </div>
-
- <div class="row"
- *ngFor="let mdsCounter of objectValues(mdsCounters); trackBy: trackByFn">
- <div class="cold-md-12">
- <cd-cephfs-chart [mdsCounter]="mdsCounter"></cd-cephfs-chart>
- </div>
- </div>
-
- <!-- templates -->
- <ng-template #poolUsageTpl
- let-row="row">
- <cd-usage-bar [totalBytes]="row.size"
- [usedBytes]="row.used"></cd-usage-bar>
- </ng-template>
-
- <ng-template #activityTmpl
- let-row="row"
- let-value="value">
- {{ row.state === 'standby-replay' ? 'Evts' : 'Reqs' }}: {{ value | dimless }} /s
- </ng-template>
- </tab>
- <tab i18n-heading
- heading="Clients: {{ clientCount }}"
- (select)="clientsSelect=true"
- (deselect)="clientsSelect=false">
- <cd-clients [id]="id" *ngIf="clientsSelect"></cd-clients>
- </tab>
-</tabset>
+++ /dev/null
-.progress {
- margin-bottom: 0px;
-}
+++ /dev/null
-import { NO_ERRORS_SCHEMA } from '@angular/core';
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { RouterTestingModule } from '@angular/router/testing';
-
-import { Observable } from 'rxjs/Observable';
-
-import { CephfsService } from '../../../shared/api/cephfs.service';
-import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
-import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
-import { FormatterService } from '../../../shared/services/formatter.service';
-import { CephfsComponent } from './cephfs.component';
-
-describe('CephfsComponent', () => {
- let component: CephfsComponent;
- let fixture: ComponentFixture<CephfsComponent>;
-
- const fakeFilesystemService = {
- getCephfs: (id) => {
- return Observable.create((observer) => {
- return () => console.log('disposed');
- });
- },
- getMdsCounters: (id) => {
- return Observable.create((observer) => {
- return () => console.log('disposed');
- });
- }
- };
-
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports: [RouterTestingModule],
- schemas: [NO_ERRORS_SCHEMA],
- declarations: [CephfsComponent, DimlessPipe],
- providers: [
- DimlessPipe,
- DimlessBinaryPipe,
- FormatterService,
- { provide: CephfsService, useValue: fakeFilesystemService }
- ]
- }).compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(CephfsComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
+++ /dev/null
-import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
-
-import * as _ from 'lodash';
-
-import { CephfsService } from '../../../shared/api/cephfs.service';
-import { CdTableSelection } from '../../../shared/models/cd-table-selection';
-import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
-import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
-
-@Component({
- selector: 'cd-cephfs',
- templateUrl: './cephfs.component.html',
- styleUrls: ['./cephfs.component.scss']
-})
-export class CephfsComponent implements OnChanges, OnInit {
- @ViewChild('poolUsageTpl') poolUsageTpl: TemplateRef<any>;
- @ViewChild('activityTmpl') activityTmpl: TemplateRef<any>;
-
- @Input() selection: CdTableSelection;
-
- selectedItem: any;
-
- id: number;
- name: string;
- ranks: any;
- pools: any;
- standbys = [];
- clientCount: number;
- mdsCounters = {};
-
- objectValues = Object.values;
- clientsSelect = false;
-
- constructor(
- private cephfsService: CephfsService,
- private dimlessBinary: DimlessBinaryPipe,
- private dimless: DimlessPipe
- ) {}
-
- ngOnChanges() {
- if (this.selection.hasSelection) {
- this.selectedItem = this.selection.first();
-
- if (this.id !== this.selectedItem.id) {
- this.id = this.selectedItem.id;
- this.ranks.data = [];
- this.pools.data = [];
- this.standbys = [];
- this.mdsCounters = {};
- }
- }
- }
-
- ngOnInit() {
- this.ranks = {
- columns: [
- { prop: 'rank' },
- { prop: 'state' },
- { prop: 'mds', name: 'Daemon' },
- { prop: 'activity', cellTemplate: this.activityTmpl },
- { prop: 'dns', name: 'Dentries', pipe: this.dimless },
- { prop: 'inos', name: 'Inodes', pipe: this.dimless }
- ],
- data: []
- };
-
- this.pools = {
- columns: [
- { prop: 'pool' },
- { prop: 'type' },
- { prop: 'size', pipe: this.dimlessBinary },
- {
- name: 'Usage',
- cellTemplate: this.poolUsageTpl,
- comparator: (valueA, valueB, rowA, rowB, sortDirection) => {
- const valA = rowA.used / rowA.avail;
- const valB = rowB.used / rowB.avail;
-
- if (valA === valB) {
- return 0;
- }
-
- if (valA > valB) {
- return 1;
- } else {
- return -1;
- }
- }
- }
- ],
- data: []
- };
- }
-
- refresh() {
- this.cephfsService.getCephfs(this.id).subscribe((data: any) => {
- this.ranks.data = data.cephfs.ranks;
- this.pools.data = data.cephfs.pools;
- this.pools.data.forEach((pool) => {
- pool.size = pool.used + pool.avail;
- });
- this.standbys = [
- {
- key: 'Standby daemons',
- value: data.standbys.map((value) => value.name).join(', ')
- }
- ];
- this.name = data.cephfs.name;
- this.clientCount = data.cephfs.client_count;
- });
-
- this.cephfsService.getMdsCounters(this.id).subscribe((data) => {
- _.each(this.mdsCounters, (value, key) => {
- if (data[key] === undefined) {
- delete this.mdsCounters[key];
- }
- });
-
- _.each(data, (mdsData: any, mdsName) => {
- mdsData.name = mdsName;
- this.mdsCounters[mdsName] = mdsData;
- });
- });
- }
-
- trackByFn(index, item) {
- return item.name;
- }
-}