Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cf Cell: Applications list #3107

Merged
merged 10 commits into from
Oct 5, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ import { EditSpaceComponent } from './edit-space/edit-space.component';
import { CloudFoundryEndpointService } from './services/cloud-foundry-endpoint.service';
import { CloudFoundryOrganizationService } from './services/cloud-foundry-organization.service';
import { CloudFoundryBuildPacksComponent } from './tabs/cloud-foundry-build-packs/cloud-foundry-build-packs.component';
import {
CloudFoundryCellAppsComponent,
} from './tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-apps/cloud-foundry-cell-apps.component';
import {
CloudFoundryCellBaseComponent,
} from './tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-base/cloud-foundry-cell-base.component';
Expand Down Expand Up @@ -104,6 +107,7 @@ import { UsersRolesComponent } from './users/manage-users/manage-users.component
CloudFoundryCellsComponent,
CloudFoundryCellBaseComponent,
CloudFoundryCellSummaryComponent,
CloudFoundryCellAppsComponent,
CloudFoundryCellChartsComponent,
CloudFoundryBuildPacksComponent,
CloudFoundryStacksComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { CloudFoundryComponent } from './cloud-foundry/cloud-foundry.component';
import { EditOrganizationComponent } from './edit-organization/edit-organization.component';
import { EditSpaceComponent } from './edit-space/edit-space.component';
import { CloudFoundryBuildPacksComponent } from './tabs/cloud-foundry-build-packs/cloud-foundry-build-packs.component';
import {
CloudFoundryCellAppsComponent,
} from './tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-apps/cloud-foundry-cell-apps.component';
import {
CloudFoundryCellBaseComponent,
} from './tabs/cloud-foundry-cells/cloud-foundry-cell/cloud-foundry-cell-base/cloud-foundry-cell-base.component';
Expand Down Expand Up @@ -198,6 +201,10 @@ const cloudFoundry: Routes = [{
{
path: 'charts',
component: CloudFoundryCellChartsComponent
},
{
path: 'apps',
component: CloudFoundryCellAppsComponent
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<app-list></app-list>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { BaseTestModules } from '../../../../../../test-framework/cloud-foundry-endpoint-service.helper';
import { ActiveRouteCfCell } from '../../../../cf-page.types';
import { CloudFoundryCellAppsComponent } from './cloud-foundry-cell-apps.component';


describe('CloudFoundryCellAppsComponent', () => {
let component: CloudFoundryCellAppsComponent;
let fixture: ComponentFixture<CloudFoundryCellAppsComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
CloudFoundryCellAppsComponent,
],
providers: [ActiveRouteCfCell],
imports: [...BaseTestModules],
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(CloudFoundryCellAppsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Component } from '@angular/core';

import {
CfCellAppsListConfigService,
} from '../../../../../../shared/components/list/list-types/cf-cell-apps/cf-cell-apps-list-config.service';
import { ListConfig } from '../../../../../../shared/components/list/list.component.types';

@Component({
selector: 'app-cloud-foundry-cell-apps',
templateUrl: './cloud-foundry-cell-apps.component.html',
styleUrls: ['./cloud-foundry-cell-apps.component.scss'],
providers: [
{
provide: ListConfig,
useClass: CfCellAppsListConfigService
}
]
})
export class CloudFoundryCellAppsComponent { }
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { first, map } from 'rxjs/operators';
import { IHeaderBreadcrumb } from '../../../../../../shared/components/page-header/page-header.types';
import { ISubHeaderTabs } from '../../../../../../shared/components/page-subheader/page-subheader.types';
import { entityFactory, metricSchemaKey } from '../../../../../../store/helpers/entity-factory';
import { getActiveRouteCfCellProvider } from '../../../../cf.helpers';
import { CloudFoundryEndpointService } from '../../../../services/cloud-foundry-endpoint.service';
import { CloudFoundryCellService } from '../cloud-foundry-cell.service';
import { getActiveRouteCfCellProvider } from '../../../../cf.helpers';

@Component({
selector: 'app-cloud-foundry-cell-base',
Expand All @@ -27,7 +27,11 @@ export class CloudFoundryCellBaseComponent {
},
{
link: 'charts',
label: 'Charts'
label: 'Metrics'
},
{
link: 'apps',
label: 'App Instances'
},
];

Expand All @@ -45,7 +49,7 @@ export class CloudFoundryCellBaseComponent {

this.waitForEntityId = cfCellService.healthyMetricId;
this.name$ = cfCellService.cellMetric$.pipe(
map(metric => `${metric.bosh_job_id} (${metric.bosh_deployment})`)
map(metric => `${metric.bosh_job_id}`)
);

this.breadcrumbs$ = cfEndpointService.endpoint$.pipe(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';

import { MetricsConfig } from '../../../../../../shared/components/metrics-chart/metrics-chart.component';
import { MetricsLineChartConfig } from '../../../../../../shared/components/metrics-chart/metrics-chart.types';
import {
MetricsRangeSelectorManagerService,
} from '../../../../../../shared/services/metrics-range-selector-manager.service';
import { MetricQueryType } from '../../../../../../shared/services/metrics-range-selector.types';
import { IMetricMatrixResult } from '../../../../../../store/types/base-metric.types';
import { IMetricCell } from '../../../../../../store/types/metric.types';
import { CloudFoundryCellService } from '../cloud-foundry-cell.service';
import { MetricsRangeSelectorService } from '../../../../../../shared/services/metrics-range-selector.service';

@Component({
selector: 'app-cloud-foundry-cell-charts',
Expand All @@ -27,7 +23,10 @@ export class CloudFoundryCellChartsComponent {
this.metricConfigs = [
[
this.cfCellService.buildMetricConfig('firehose_value_metric_rep_capacity_remaining_containers', MetricQueryType.RANGE_QUERY),
this.cfCellService.buildChartConfig('Containers Remaining')
{
...this.cfCellService.buildChartConfig('Containers Remaining'),
yAxisTickFormatting: (label: string) => Math.round(Number(label)).toString()
}
],
[
this.cfCellService.buildMetricConfig('firehose_value_metric_rep_capacity_remaining_memory', MetricQueryType.QUERY),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class MockCloudFoundryCellService {
chartType: MetricsChartTypes.LINE,
xAxisLabel: 'Time',
yAxisLabel: yAxisLabel,
showLegend: false
showLegend: false,
autoScale: true
})

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ export class CloudFoundryCellSummaryComponent {
MetricQueryType.QUERY,
(value) => value === '0' ? '1' : '0'
);
this.chartConfig = this.cfCellService.buildChartConfig('Cell Healthy (1)');
this.chartConfig = this.cfCellService.buildChartConfig('Cell Health');
this.chartConfig.yAxisTickFormatting = (label) => label === '1' ? 'Healthy' : 'Not Healthy';
this.chartConfig.yAxisTicks = ['0', '1'];

this.status$ = cfCellService.healthy$.pipe(
map(health => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class CloudFoundryCellService {
queryRange: MetricQueryType,
mapSeriesItemValue?: (value) => any): MetricsConfig<IMetricMatrixResult<IMetricCell>> {
return {
getSeriesName: (result: IMetricMatrixResult<IMetricCell>) => `Cell ${result.metric.bosh_job_id} (${result.metric.bosh_deployment})`,
getSeriesName: (result: IMetricMatrixResult<IMetricCell>) => `Cell ${result.metric.bosh_job_id}`,
mapSeriesItemName: MetricsChartHelpers.getDateSeriesName,
mapSeriesItemValue,
metricsAction: new FetchCFCellMetricsAction(
Expand All @@ -94,6 +94,7 @@ export class CloudFoundryCellService {
lineChartConfig.xAxisLabel = 'Time';
lineChartConfig.yAxisLabel = yAxisLabel;
lineChartConfig.showLegend = false;
lineChartConfig.autoScale = false;
return lineChartConfig;
}

Expand All @@ -102,7 +103,8 @@ export class CloudFoundryCellService {
this.cfGuid,
this.cellId,
new MetricQueryConfig(metric + `{bosh_job_id="${this.cellId}"}`, {}),
MetricQueryType.VALUE
MetricQueryType.QUERY,
false
);
if (metric === CellMetrics.HEALTHY) {
this.healthyMetricId = action.metricId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<mat-card *ngIf="appData$ | async as appData">
<app-card-status [status$]="status$"></app-card-status>
<mat-card-content *ngIf="appData.isRunning">
<mat-card-content *ngIf="appData.isRunning && appData.monitor">
<table class="instances__detail">
<tr>
<td>Usage</td>
Expand All @@ -27,4 +27,4 @@
<mat-card-title>Application is not running</mat-card-title>
</mat-card-header>
</mat-card-content>
</mat-card>
</mat-card>
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Component, Input } from '@angular/core';
import { Component, Input, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

import { pathGet } from '../../../../../core/utils.service';
import { TableCellCustom } from '../../list.types';
import { objectHelper } from './../../../../../core/helper-classes/object.helpers';
import { ICellDefinition } from './../table.types';
Expand All @@ -10,7 +12,8 @@ import { ICellDefinition } from './../table.types';
templateUrl: 'app-table-cell-default.component.html',
styleUrls: ['app-table-cell-default.component.scss']
})
export class TableCellDefaultComponent<T> extends TableCellCustom<T> {
export class TableCellDefaultComponent<T> extends TableCellCustom<T> implements OnDestroy {

public cellDefinition: ICellDefinition<T>;

private _row: T;
Expand All @@ -23,6 +26,8 @@ export class TableCellDefaultComponent<T> extends TableCellCustom<T> {
}
}

private asyncSub: Subscription;

public valueContext = { value: null };
public isLink = false;
public isExternalLink = false;
Expand All @@ -33,18 +38,49 @@ export class TableCellDefaultComponent<T> extends TableCellCustom<T> {
public init() {
this.setValueGenerator();
this.setValue(this.row);
this.isLink = !!this.cellDefinition.getLink;
if (this.isLink) {
this.linkValue = this.cellDefinition.getLink(this.row);
}
this.setSyncLink();
}

private setupLinkDeps() {
if (this.cellDefinition.newTab) {
this.linkTarget = '_blank';
}
this.isExternalLink = this.isLink && this.cellDefinition.externalLink;
}

private setSyncLink() {
if (!this.cellDefinition.getLink) {
return;
}
this.isLink = true;
this.linkValue = this.cellDefinition.getLink(this.row);
this.setupLinkDeps();
}

private setupAsyncLink(value) {
if (!this.cellDefinition.getAsyncLink) {
return;
}
this.isLink = true;
this.linkValue = this.cellDefinition.getAsyncLink(value);
this.setupLinkDeps();
}

private setupAsync(row) {
if (this.asyncSub) {
return;
}
const asyncConfig = this.cellDefinition.asyncValue;
this.asyncSub = row[asyncConfig.pathToObs].subscribe(value => {
this.valueContext.value = pathGet(asyncConfig.pathToValue, value);
this.setupAsyncLink(value);
});
}

private setValue(row: T) {
if (this.valueGenerator) {
if (this.cellDefinition && this.cellDefinition.asyncValue) {
this.setupAsync(row);
} else if (this.valueGenerator) {
this.valueContext.value = this.valueGenerator(row);
}
}
Expand All @@ -66,4 +102,10 @@ export class TableCellDefaultComponent<T> extends TableCellCustom<T> {
return null;
}

ngOnDestroy() {
if (this.asyncSub) {
this.asyncSub.unsubscribe();
}
}

}
12 changes: 12 additions & 0 deletions src/frontend/app/shared/components/list/list-table/table.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ import { listTableCells, TableCellComponent } from './table-cell/table-cell.comp
import { TableRowComponent } from './table-row/table-row.component';
import { TableComponent } from './table.component';

export interface ICellAsyncValue {
pathToObs: string;
pathToValue: string;
}

export interface ICellAsyncLink {
pathToValue: string;
}

export interface ICellDefinition<T> {
// Dot separated path to get the value from the row
valuePath?: string;
Expand All @@ -14,7 +23,10 @@ export interface ICellDefinition<T> {
externalLink?: boolean;
// Automatically turns the cell into a link
getLink?: (row: T) => string;
// Used in conjunction with asyncValue
getAsyncLink?: (value) => string;
newTab?: boolean;
asyncValue?: ICellAsyncValue;
}

export type CellConfigFunction<T> = (row: T) => any;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<a [routerLink]="[cellLink]" *ngIf="(cellMetric$ | async) as cellMetric">
{{cellMetric.bosh_job_id}} ({{cellMetric.bosh_deployment}})
</a>
<a [routerLink]="[cellLink]" *ngIf="(cellMetric$ | async) as cellMetric; else loading">
{{cellMetric.bosh_job_id}}
</a>
<ng-template #loading>
<mat-progress-spinner diameter="20" mode="indeterminate"></mat-progress-spinner>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class TableCellCfCellComponent extends TableCellCustom<ListAppInstance> i
filter(metric => !!metric),
tap(metric => {
this.cellLink = `/cloud-foundry/${cfGuid}/cells/${metric.bosh_job_id}/summary`;
// If we're polled to get metric then make sure to unsub
// If we're polling to get metric then make sure to unsub
if (this.fetchMetricsSub) {
this.fetchMetricsSub.unsubscribe();
}
Expand Down
Loading