columnMode="flex"
[columns]="columns"
[autoReload]="-1"
- (fetchData)="refresh()">
+ (fetchData)="refresh()"
+ [status]="tableStatus">
</cd-table>
<ng-template #healthTmpl
import { Subscription } from 'rxjs';
import { RbdMirroringService } from '../../../../shared/api/rbd-mirroring.service';
+import { TableStatusViewCache } from '../../../../shared/classes/table-status-view-cache';
import { CephShortVersionPipe } from '../../../../shared/pipes/ceph-short-version.pipe';
@Component({
data: [];
columns: {};
+ tableStatus = new TableStatusViewCache();
+
constructor(
private rbdMirroringService: RbdMirroringService,
private cephShortVersionPipe: CephShortVersionPipe
this.subs = this.rbdMirroringService.subscribeSummary((data) => {
this.data = data.content_data.daemons;
+ this.tableStatus = new TableStatusViewCache(data.status);
});
}
columnMode="flex"
[columns]="image_error.columns"
[autoReload]="-1"
- (fetchData)="refresh()">
+ (fetchData)="refresh()"
+ [status]="tableStatus">
</cd-table>
</ng-template>
</li>
columnMode="flex"
[columns]="image_syncing.columns"
[autoReload]="-1"
- (fetchData)="refresh()">
+ (fetchData)="refresh()"
+ [status]="tableStatus">
</cd-table>
</ng-template>
</li>
columnMode="flex"
[columns]="image_ready.columns"
[autoReload]="-1"
- (fetchData)="refresh()">
+ (fetchData)="refresh()"
+ [status]="tableStatus">
</cd-table>
</ng-template>
</li>
import { Subscription } from 'rxjs';
import { RbdMirroringService } from '../../../../shared/api/rbd-mirroring.service';
+import { TableStatusViewCache } from '../../../../shared/classes/table-status-view-cache';
@Component({
selector: 'cd-mirroring-images',
columns: {}
};
+ tableStatus = new TableStatusViewCache();
+
constructor(private rbdMirroringService: RbdMirroringService) {}
ngOnInit() {
this.image_error.data = data.content_data.image_error;
this.image_syncing.data = data.content_data.image_syncing;
this.image_ready.data = data.content_data.image_ready;
+ this.tableStatus = new TableStatusViewCache(data.status);
});
}
-<cd-view-cache [status]="status"></cd-view-cache>
-
<div class="row">
<div class="col-md-12">
<span><strong i18n>Site Name:</strong> {{siteName}}</span>
[autoReload]="-1"
(fetchData)="refresh()"
selectionType="single"
- (updateSelection)="updateSelection($event)">
+ (updateSelection)="updateSelection($event)"
+ [status]="tableStatus">
<cd-table-actions class="table-actions"
[permission]="permission"
[selection]="selection"
import { Observable, Subscriber, Subscription } from 'rxjs';
import { RbdMirroringService } from '../../../../shared/api/rbd-mirroring.service';
+import { TableStatusViewCache } from '../../../../shared/classes/table-status-view-cache';
import { CriticalConfirmationModalComponent } from '../../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
import { Icons } from '../../../../shared/enum/icons.enum';
import { CdTableAction } from '../../../../shared/models/cd-table-action';
data: [];
columns: {};
+ tableStatus = new TableStatusViewCache();
+
constructor(
private authStorageService: AuthStorageService,
private rbdMirroringService: RbdMirroringService,
this.subs = this.rbdMirroringService.subscribeSummary((data) => {
this.data = data.content_data.pools;
+ this.tableStatus = new TableStatusViewCache(data.status);
});
}
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
-import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { ChartsModule } from 'ng2-charts';
ComponentsModule,
NgbDropdownModule,
ChartsModule,
- PipesModule
+ PipesModule,
+ NgbTooltipModule
],
declarations: [RbdConfigurationListComponent, TableComponent],
providers: [FormatterService, RbdConfigurationService]
<cd-rbd-tabs></cd-rbd-tabs>
-<cd-view-cache *ngFor="let viewCacheStatus of viewCacheStatusList"
- [status]="viewCacheStatus.status"
- [statusFor]="viewCacheStatus.statusFor"></cd-view-cache>
-
<cd-table #table
[data]="images"
columnMode="flex"
forceIdentifier="true"
selectionType="single"
[hasDetails]="true"
+ [status]="tableStatus"
+ [autoReload]="-1"
+ (fetchData)="taskListService.fetch()"
(setExpandedRow)="setExpandedRow($event)"
(updateSelection)="updateSelection($event)">
<cd-table-actions class="table-actions"
PermissionHelper
} from '../../../../testing/unit-test-helper';
import { RbdService } from '../../../shared/api/rbd.service';
+import { TableStatusViewCache } from '../../../shared/classes/table-status-view-cache';
import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
import { ExecutingTask } from '../../../shared/models/executing-task';
spyOn(component.table, 'reset');
summaryService['summaryDataSource'].error(undefined);
expect(component.table.reset).toHaveBeenCalled();
- expect(component.viewCacheStatusList).toEqual([{ status: ViewCacheStatus.ValueException }]);
+ expect(component.tableStatus).toEqual(
+ new TableStatusViewCache(ViewCacheStatus.ValueException)
+ );
});
});
import { RbdService } from '../../../shared/api/rbd.service';
import { ListWithDetails } from '../../../shared/classes/list-with-details.class';
+import { TableStatusViewCache } from '../../../shared/classes/table-status-view-cache';
import { ConfirmationModalComponent } from '../../../shared/components/confirmation-modal/confirmation-modal.component';
import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
images: any;
columns: CdTableColumn[];
retries: number;
- viewCacheStatusList: any[];
+ tableStatus = new TableStatusViewCache();
selection = new CdTableSelection();
modalRef: NgbModalRef;
private dimlessPipe: DimlessPipe,
private modalService: ModalService,
private taskWrapper: TaskWrapperService,
- private taskListService: TaskListService,
+ public taskListService: TaskListService,
private urlBuilder: URLBuilderService,
public actionLabels: ActionLabelsI18n
) {
onFetchError() {
this.table.reset(); // Disable loading indicator.
- this.viewCacheStatusList = [{ status: ViewCacheStatus.ValueException }];
+ this.tableStatus = new TableStatusViewCache(ViewCacheStatus.ValueException);
}
prepareResponse(resp: any[]): any[] {
let images: any[] = [];
const viewCacheStatusMap = {};
+
resp.forEach((pool) => {
if (_.isUndefined(viewCacheStatusMap[pool.status])) {
viewCacheStatusMap[pool.status] = [];
viewCacheStatusMap[pool.status].push(pool.pool_name);
images = images.concat(pool.value);
});
- const viewCacheStatusList: any[] = [];
- _.forEach(viewCacheStatusMap, (value: any, key) => {
- viewCacheStatusList.push({
- status: parseInt(key, 10),
- statusFor:
- (value.length > 1 ? 'pools ' : 'pool ') +
- '<strong>' +
- value.join('</strong>, <strong>') +
- '</strong>'
- });
- });
- this.viewCacheStatusList = viewCacheStatusList;
+
+ let status: number;
+ if (viewCacheStatusMap[ViewCacheStatus.ValueException]) {
+ status = ViewCacheStatus.ValueException;
+ } else if (viewCacheStatusMap[ViewCacheStatus.ValueStale]) {
+ status = ViewCacheStatus.ValueStale;
+ } else if (viewCacheStatusMap[ViewCacheStatus.ValueNone]) {
+ status = ViewCacheStatus.ValueNone;
+ }
+
+ if (status) {
+ const statusFor =
+ (viewCacheStatusMap[status].length > 1 ? 'pools ' : 'pool ') +
+ viewCacheStatusMap[status].join();
+
+ this.tableStatus = new TableStatusViewCache(status, statusFor);
+ } else {
+ this.tableStatus = new TableStatusViewCache();
+ }
+
return images;
}
<cd-rbd-tabs></cd-rbd-tabs>
-<cd-view-cache *ngFor="let viewCacheStatus of viewCacheStatusList"
- [status]="viewCacheStatus.status"
- [statusFor]="viewCacheStatus.statusFor"></cd-view-cache>
-
<cd-table [data]="images"
columnMode="flex"
[columns]="columns"
identifier="id"
forceIdentifier="true"
selectionType="single"
+ [status]="tableStatus"
+ [autoReload]="-1"
+ (fetchData)="taskListService.fetch()"
(updateSelection)="updateSelection($event)">
<div class="table-actions btn-toolbar">
<cd-table-actions class="btn-group"
import * as moment from 'moment';
import { RbdService } from '../../../shared/api/rbd.service';
+import { TableStatusViewCache } from '../../../shared/classes/table-status-view-cache';
import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
import { TableComponent } from '../../../shared/datatable/table/table.component';
retries: number;
selection = new CdTableSelection();
tableActions: CdTableAction[];
- viewCacheStatusList: any[];
+ tableStatus = new TableStatusViewCache();
disablePurgeBtn = true;
constructor(
private rbdService: RbdService,
private modalService: ModalService,
private cdDatePipe: CdDatePipe,
- private taskListService: TaskListService,
+ public taskListService: TaskListService,
private taskWrapper: TaskWrapperService,
public actionLabels: ActionLabelsI18n
) {
prepareResponse(resp: any[]): any[] {
let images: any[] = [];
const viewCacheStatusMap = {};
+
resp.forEach((pool: Record<string, any>) => {
if (_.isUndefined(viewCacheStatusMap[pool.status])) {
viewCacheStatusMap[pool.status] = [];
this.disablePurgeBtn = !images.length;
});
- const viewCacheStatusList: any[] = [];
- _.forEach(viewCacheStatusMap, (value: any, key) => {
- viewCacheStatusList.push({
- status: parseInt(key, 10),
- statusFor:
- (value.length > 1 ? 'pools ' : 'pool ') +
- '<strong>' +
- value.join('</strong>, <strong>') +
- '</strong>'
- });
- });
- this.viewCacheStatusList = viewCacheStatusList;
+ let status: number;
+ if (viewCacheStatusMap[3]) {
+ status = 3;
+ } else if (viewCacheStatusMap[1]) {
+ status = 1;
+ } else if (viewCacheStatusMap[2]) {
+ status = 2;
+ }
+
+ if (status) {
+ const statusFor =
+ (viewCacheStatusMap[status].length > 1 ? 'pools ' : 'pool ') +
+ viewCacheStatusMap[status].join();
+
+ this.tableStatus = new TableStatusViewCache(status, statusFor);
+ } else {
+ this.tableStatus = new TableStatusViewCache();
+ }
+
images.forEach((image) => {
image.cdIsExpired = moment().isAfter(image.deferment_end_time);
});
+
return images;
}
onFetchError() {
this.table.reset(); // Disable loading indicator.
- this.viewCacheStatusList = [{ status: ViewCacheStatus.ValueException }];
+ this.tableStatus = new TableStatusViewCache(ViewCacheStatus.ValueException);
}
updateSelection(selection: CdTableSelection) {
-<cd-view-cache [status]="clients.status"></cd-view-cache>
-
<cd-table [data]="clients.data"
[columns]="columns"
+ [status]="clients.status"
+ [autoReload]="-1"
+ (fetchData)="triggerApiUpdate.emit()"
selectionType="single"
(updateSelection)="updateSelection($event)">
<cd-table-actions class="table-actions"
import { ToastrModule } from 'ngx-toastr';
import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
+import { TableStatusViewCache } from '../../../shared/classes/table-status-view-cache';
import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
import { SharedModule } from '../../../shared/shared.module';
fixture = TestBed.createComponent(CephfsClientsComponent);
component = fixture.componentInstance;
component.clients = {
- status: ViewCacheStatus.ValueOk,
+ status: new TableStatusViewCache(ViewCacheStatus.ValueOk),
data: [{}, {}, {}, {}]
};
});
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { CephfsService } from '../../../shared/api/cephfs.service';
+import { TableStatusViewCache } from '../../../shared/classes/table-status-view-cache';
import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
import { Icons } from '../../../shared/enum/icons.enum';
import { NotificationType } from '../../../shared/enum/notification-type.enum';
-import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
import { CdTableAction } from '../../../shared/models/cd-table-action';
import { CdTableColumn } from '../../../shared/models/cd-table-column';
import { CdTableSelection } from '../../../shared/models/cd-table-selection';
@Input()
clients: {
data: any[];
- status: ViewCacheStatus;
+ status: TableStatusViewCache;
};
@Output()
import { configureTestBed } from '../../../../testing/unit-test-helper';
import { CephfsService } from '../../../shared/api/cephfs.service';
+import { TableStatusViewCache } from '../../../shared/classes/table-status-view-cache';
import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
import { SharedModule } from '../../../shared/shared.module';
import { CephfsClientsComponent } from '../cephfs-clients/cephfs-clients.component';
};
const defaultClients: Record<string, any> = {
data: [],
- status: ViewCacheStatus.ValueNone
+ status: new TableStatusViewCache(ViewCacheStatus.ValueNone)
};
component['subscribeInterval'] = () => undefined;
updateData();
import { Subscription, timer } from 'rxjs';
import { CephfsService } from '../../../shared/api/cephfs.service';
+import { TableStatusViewCache } from '../../../shared/classes/table-status-view-cache';
import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum';
import { Permission } from '../../../shared/models/permissions';
import { AuthStorageService } from '../../../shared/services/auth-storage.service';
id: number;
clients: Record<string, any> = {
data: [],
- status: ViewCacheStatus.ValueNone
+ status: new TableStatusViewCache(ViewCacheStatus.ValueNone)
};
// Details tab
};
this.clients = {
data: [],
- status: ViewCacheStatus.ValueNone
+ status: new TableStatusViewCache(ViewCacheStatus.ValueNone)
};
this.updateInterval();
}
this.softRefresh();
},
() => {
- this.clients.status = ViewCacheStatus.ValueException;
+ this.clients.status = new TableStatusViewCache(ViewCacheStatus.ValueException);
}
);
}
const data = _.cloneDeep(this.data); // Forces update of tab tables on tab switch
// Clients tab
this.clients = data.clients;
+ this.clients.status = new TableStatusViewCache(this.clients.status);
// Details tab
this.details = {
standbys: data.standbys,
<a ngbNavLink
i18n>Pools List</a>
<ng-template ngbNavContent>
- <cd-view-cache *ngFor="let viewCacheStatus of viewCacheStatusList"
- [status]="viewCacheStatus.status"
- [statusFor]="viewCacheStatus.statusFor"></cd-view-cache>
-
<cd-table #table
id="pool-list"
[data]="pools"
[columns]="columns"
selectionType="single"
[hasDetails]="true"
+ [status]="tableStatus"
+ [autoReload]="-1"
+ (fetchData)="taskListService.fetch()"
(setExpandedRow)="setExpandedRow($event)"
(updateSelection)="updateSelection($event)">
<cd-table-actions id="pool-list-actions"
import { ConfigurationService } from '../../../shared/api/configuration.service';
import { PoolService } from '../../../shared/api/pool.service';
import { ListWithDetails } from '../../../shared/classes/list-with-details.class';
+import { TableStatusViewCache } from '../../../shared/classes/table-status-view-cache';
import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
import { ActionLabelsI18n, URLVerbs } from '../../../shared/constants/app.constants';
import { TableComponent } from '../../../shared/datatable/table/table.component';
executingTasks: ExecutingTask[] = [];
permissions: Permissions;
tableActions: CdTableAction[];
- viewCacheStatusList: any[];
+ tableStatus = new TableStatusViewCache();
cacheTiers: any[] = [];
monAllowPoolDelete = false;
private poolService: PoolService,
private taskWrapper: TaskWrapperService,
private authStorageService: AuthStorageService,
- private taskListService: TaskListService,
+ public taskListService: TaskListService,
private modalService: ModalService,
private pgCategoryService: PgCategoryService,
private dimlessPipe: DimlessPipe,
this.taskListService.init(
() => this.poolService.getList(),
undefined,
- (pools) => (this.pools = this.transformPoolsData(pools)),
+ (pools) => {
+ this.pools = this.transformPoolsData(pools);
+ this.tableStatus = new TableStatusViewCache();
+ },
() => {
this.table.reset(); // Disable loading indicator.
- this.viewCacheStatusList = [{ status: ViewCacheStatus.ValueException }];
+ this.tableStatus = new TableStatusViewCache(ViewCacheStatus.ValueException);
},
(task) => task.name.startsWith(`${BASE_URL}/`),
(pool, task) => task.metadata['pool_name'] === pool.pool_name,
-<cd-alert-panel *ngIf="isStale"
- type="warning"
- size="slim"
- i18n>The bucket list data might be stale. If needed, you can manually reload it.</cd-alert-panel>
<cd-table #table
[autoReload]="false"
[data]="buckets"
(setExpandedRow)="setExpandedRow($event)"
(updateSelection)="updateSelection($event)"
identifier="bid"
- (fetchData)="getBucketList($event)">
+ (fetchData)="getBucketList($event)"
+ [status]="tableStatus">
<cd-table-actions class="table-actions"
[permission]="permission"
[selection]="selection"
import { RgwBucketService } from '../../../shared/api/rgw-bucket.service';
import { ListWithDetails } from '../../../shared/classes/list-with-details.class';
+import { TableStatus } from '../../../shared/classes/table-status';
import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
import { TableComponent } from '../../../shared/datatable/table/table.component';
columns: CdTableColumn[] = [];
buckets: object[] = [];
selection: CdTableSelection = new CdTableSelection();
- isStale = false;
+ tableStatus = new TableStatus();
staleTimeout: number;
constructor(
this.ngZone.runOutsideAngular(() => {
this.staleTimeout = window.setTimeout(() => {
this.ngZone.run(() => {
- this.isStale = true;
+ this.tableStatus = new TableStatus(
+ 'warning',
+ $localize`The bucket list data might be stale. If needed, you can manually reload it.`
+ );
});
}, 10000);
});
}
getBucketList(context: CdTableFetchDataContext) {
- this.isStale = false;
+ this.tableStatus = new TableStatus();
this.timeConditionReached();
this.rgwBucketService.list().subscribe(
(resp: object[]) => {
-<cd-alert-panel *ngIf="isStale"
- type="warning"
- size="slim"
- i18n>The user list data might be stale. If needed, you can manually reload it.</cd-alert-panel>
<cd-table #table
[autoReload]="false"
[data]="users"
(setExpandedRow)="setExpandedRow($event)"
(updateSelection)="updateSelection($event)"
identifier="uid"
- (fetchData)="getUserList($event)">
+ (fetchData)="getUserList($event)"
+ [status]="tableStatus">
<cd-table-actions class="table-actions"
[permission]="permission"
[selection]="selection"
import { RgwUserService } from '../../../shared/api/rgw-user.service';
import { ListWithDetails } from '../../../shared/classes/list-with-details.class';
+import { TableStatus } from '../../../shared/classes/table-status';
import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
import { TableComponent } from '../../../shared/datatable/table/table.component';
columns: CdTableColumn[] = [];
users: object[] = [];
selection: CdTableSelection = new CdTableSelection();
- isStale = false;
+ tableStatus = new TableStatus();
staleTimeout: number;
constructor(
this.ngZone.runOutsideAngular(() => {
this.staleTimeout = window.setTimeout(() => {
this.ngZone.run(() => {
- this.isStale = true;
+ this.tableStatus = new TableStatus(
+ 'warning',
+ $localize`The user list data might be stale. If needed, you can manually reload it.`
+ );
});
}, 10000);
});
}
getUserList(context: CdTableFetchDataContext) {
- this.isStale = false;
+ this.tableStatus = new TableStatus();
this.timeConditionReached();
this.rgwUserService.list().subscribe(
(resp: object[]) => {
--- /dev/null
+import { ViewCacheStatus } from '../enum/view-cache-status.enum';
+import { TableStatusViewCache } from './table-status-view-cache';
+
+describe('TableStatusViewCache', () => {
+ it('should create an instance', () => {
+ const ts = new TableStatusViewCache();
+ expect(ts).toBeTruthy();
+ expect(ts).toEqual({ msg: '', type: 'light' });
+ });
+
+ it('should create a ValueStale instance', () => {
+ let ts = new TableStatusViewCache(ViewCacheStatus.ValueStale);
+ expect(ts).toEqual({ type: 'warning', msg: 'Displaying previously cached data.' });
+
+ ts = new TableStatusViewCache(ViewCacheStatus.ValueStale, 'foo bar');
+ expect(ts).toEqual({ type: 'warning', msg: 'Displaying previously cached data for foo bar.' });
+ });
+
+ it('should create a ValueNone instance', () => {
+ let ts = new TableStatusViewCache(ViewCacheStatus.ValueNone);
+ expect(ts).toEqual({ type: 'info', msg: 'Retrieving data. Please wait...' });
+
+ ts = new TableStatusViewCache(ViewCacheStatus.ValueNone, 'foo bar');
+ expect(ts).toEqual({ type: 'info', msg: 'Retrieving data for foo bar. Please wait...' });
+ });
+
+ it('should create a ValueException instance', () => {
+ let ts = new TableStatusViewCache(ViewCacheStatus.ValueException);
+ expect(ts).toEqual({
+ type: 'danger',
+ msg: 'Could not load data. Please check the cluster health.'
+ });
+
+ ts = new TableStatusViewCache(ViewCacheStatus.ValueException, 'foo bar');
+ expect(ts).toEqual({
+ type: 'danger',
+ msg: 'Could not load data for foo bar. Please check the cluster health.'
+ });
+ });
+});
--- /dev/null
+import { ViewCacheStatus } from '../enum/view-cache-status.enum';
+import { TableStatus } from './table-status';
+
+export class TableStatusViewCache extends TableStatus {
+ constructor(status: ViewCacheStatus = ViewCacheStatus.ValueOk, statusFor: string = '') {
+ super();
+
+ switch (status) {
+ case ViewCacheStatus.ValueOk:
+ this.type = 'light';
+ this.msg = '';
+ break;
+ case ViewCacheStatus.ValueNone:
+ this.type = 'info';
+ this.msg =
+ (statusFor ? $localize`Retrieving data for ${statusFor}.` : $localize`Retrieving data.`) +
+ ' ' +
+ $localize`Please wait...`;
+ break;
+ case ViewCacheStatus.ValueStale:
+ this.type = 'warning';
+ this.msg = statusFor
+ ? $localize`Displaying previously cached data for ${statusFor}.`
+ : $localize`Displaying previously cached data.`;
+ break;
+ case ViewCacheStatus.ValueException:
+ this.type = 'danger';
+ this.msg =
+ (statusFor
+ ? $localize`Could not load data for ${statusFor}.`
+ : $localize`Could not load data.`) +
+ ' ' +
+ $localize`Please check the cluster health.`;
+ break;
+ }
+ }
+}
--- /dev/null
+import { TableStatus } from './table-status';
+
+describe('TableStatus', () => {
+ it('should create an instance', () => {
+ const ts = new TableStatus();
+ expect(ts).toBeTruthy();
+ expect(ts).toEqual({ msg: '', type: 'light' });
+ });
+
+ it('should create with parameters', () => {
+ const ts = new TableStatus('danger', 'foo');
+ expect(ts).toBeTruthy();
+ expect(ts).toEqual({ msg: 'foo', type: 'danger' });
+ });
+});
--- /dev/null
+export class TableStatus {
+ constructor(public type: 'info' | 'warning' | 'danger' | 'light' = 'light', public msg = '') {}
+}
import { SubmitButtonComponent } from './submit-button/submit-button.component';
import { TelemetryNotificationComponent } from './telemetry-notification/telemetry-notification.component';
import { UsageBarComponent } from './usage-bar/usage-bar.component';
-import { ViewCacheComponent } from './view-cache/view-cache.component';
@NgModule({
imports: [
NgbTimepickerModule
],
declarations: [
- ViewCacheComponent,
SparklineComponent,
HelperComponent,
SelectBadgesComponent,
],
providers: [],
exports: [
- ViewCacheComponent,
SparklineComponent,
HelperComponent,
SelectBadgesComponent,
+++ /dev/null
-<cd-alert-panel type="info"
- *ngIf="status === vcs.ValueNone">
- <ng-container i18n>Retrieving data<span *ngIf="statusFor"> for
- <span [innerHtml]="statusFor"></span></span>. Please wait...</ng-container>
-</cd-alert-panel>
-
-<cd-alert-panel *ngIf="status === vcs.ValueStale"
- type="warning">
- <ng-container i18n>Displaying previously cached data<span *ngIf="statusFor">
- for <span [innerHtml]="statusFor"></span></span>.</ng-container>
-</cd-alert-panel>
-
-<cd-alert-panel type="error"
- *ngIf="status === vcs.ValueException">
- <ng-container i18n>Could not load data<span *ngIf="statusFor"> for
- <span [innerHtml]="statusFor"></span></span>.
- Please check the cluster health.</ng-container>
-</cd-alert-panel>
+++ /dev/null
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
-
-import { configureTestBed } from '../../../../testing/unit-test-helper';
-import { AlertPanelComponent } from '../alert-panel/alert-panel.component';
-import { ViewCacheComponent } from './view-cache.component';
-
-describe('ViewCacheComponent', () => {
- let component: ViewCacheComponent;
- let fixture: ComponentFixture<ViewCacheComponent>;
-
- configureTestBed({
- declarations: [ViewCacheComponent, AlertPanelComponent],
- imports: [NgbAlertModule]
- });
-
- beforeEach(() => {
- fixture = TestBed.createComponent(ViewCacheComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
+++ /dev/null
-import { Component, Input } from '@angular/core';
-
-import { ViewCacheStatus } from '../../enum/view-cache-status.enum';
-
-@Component({
- selector: 'cd-view-cache',
- templateUrl: './view-cache.component.html',
- styleUrls: ['./view-cache.component.scss']
-})
-export class ViewCacheComponent {
- @Input()
- status: ViewCacheStatus;
- @Input()
- statusFor: string;
- vcs = ViewCacheStatus;
-}
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
-import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { ComponentsModule } from '../components/components.module';
NgxDatatableModule,
FormsModule,
NgbDropdownModule,
+ NgbTooltipModule,
PipesModule,
ComponentsModule,
RouterModule
import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
-import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { configureTestBed } from '../../../../testing/unit-test-helper';
ComponentsModule,
RouterTestingModule,
NgbDropdownModule,
- PipesModule
+ PipesModule,
+ NgbTooltipModule
]
});
-<cd-alert-panel type="error"
- *ngIf="loadingError"
- i18n>Failed to load data.</cd-alert-panel>
-
<div class="dataTables_wrapper">
<div *ngIf="onlyActionHeader"
*ngIf="fetchData.observers.length > 0">
<button type="button"
- class="btn btn-light"
+ [class]="'btn btn-' + status.type"
+ [ngbTooltip]="status.msg"
(click)="refreshBtn()">
<i [ngClass]="[icons.large, icons.refresh]"
[class.fa-spin]="updating || loadingIndicator"></i>
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
-import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgbDropdownModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import * as _ from 'lodash';
ComponentsModule,
RouterTestingModule,
NgbDropdownModule,
- PipesModule
+ PipesModule,
+ NgbTooltipModule
]
});
component.data = createFakeData(5);
component.fetchData.subscribe((context: any) => {
context.error();
- expect(component.loadingError).toBeTruthy();
+ expect(component.status.type).toBe('danger');
expect(component.data.length).toBe(0);
expect(component.loadingIndicator).toBeFalsy();
expect(component['updating']).toBeFalsy();
context.errorConfig.resetData = false;
context.errorConfig.displayError = false;
context.error();
- expect(component.loadingError).toBeFalsy();
+ expect(component.status.type).toBe('danger');
expect(component.data.length).toBe(10);
expect(component.loadingIndicator).toBeFalsy();
expect(component['updating']).toBeFalsy();
import * as _ from 'lodash';
import { Observable, Subject, Subscription, timer as observableTimer } from 'rxjs';
+import { TableStatus } from '../../../shared/classes/table-status';
import { Icons } from '../../../shared/enum/icons.enum';
import { CellTemplate } from '../../enum/cell-template.enum';
import { CdTableColumn } from '../../models/cd-table-column';
@Input()
extraFilterableColumns: CdTableColumn[] = [];
+ @Input()
+ status = new TableStatus();
+
/**
* Should be a function to update the input data if undefined nothing will be triggered
*
search = '';
rows: any[] = [];
loadingIndicator = true;
- loadingError = false;
paginationClasses = {
pagerLeftArrow: Icons.leftArrowDouble,
pagerRightArrow: Icons.rightArrowDouble,
reloadData() {
if (!this.updating) {
- this.loadingError = false;
+ this.status = new TableStatus();
const context = new CdTableFetchDataContext(() => {
// Do we have to display the error panel?
- this.loadingError = context.errorConfig.displayError;
+ if (!!context.errorConfig.displayError) {
+ this.status = new TableStatus('danger', $localize`Failed to load data.`);
+ }
// Force data table to show no data?
if (context.errorConfig.resetData) {
this.data = [];
export interface MirroringSummary {
content_data?: any;
site_name?: any;
+ status?: any;
}
import { Observable, Subscription } from 'rxjs';
import { ExecutingTask } from '../models/executing-task';
+import { Summary } from '../models/summary.model';
import { SummaryService } from './summary.service';
import { TaskMessageService } from './task-message.service';
taskFilter: (task: ExecutingTask) => boolean;
itemFilter: (item: any, task: ExecutingTask) => boolean;
builders: object;
+ summary: Summary;
constructor(
private taskMessageService: TaskMessageService,
this.builders = builders || {};
this.summaryDataSubscription = this.summaryService.subscribe((summary) => {
- this.getUpdate().subscribe((resp: any) => {
- this.updateData(resp, summary['executing_tasks'].filter(this.taskFilter));
- }, this.onFetchError);
+ this.summary = summary;
+ this.fetch();
+ }, this.onFetchError);
+ }
+
+ fetch() {
+ this.getUpdate().subscribe((resp: any) => {
+ this.updateData(resp, this.summary['executing_tasks'].filter(this.taskFilter));
}, this.onFetchError);
}