src/app/streams/streams/streams.component.ts
encapsulation | ViewEncapsulation.None |
selector | app-streams |
styleUrls | styles.scss |
templateUrl | ./streams.component.html |
constructor(streamsService: StreamsService, modalService: BsModalService, appsService: AppsService, notificationService: NotificationService, loggerService: LoggerService, authService: AuthService, sharedAboutService: SharedAboutService, grafanaService: GrafanaService, blockerService: BlockerService, router: Router)
|
||||||||||||||||||||||||||||||||||||||||||||
Initialize component
Parameters :
|
applyAction |
applyAction(action: string, args?: any)
|
Apply Action
Returns :
void
|
applySort | ||||||||
applySort(sort: SortParams)
|
||||||||
Apply sort Triggered on column header click
Parameters :
Returns :
void
|
canShowDeploymentInfo | ||||||||
canShowDeploymentInfo(item: StreamDefinition)
|
||||||||
Determine show deployment info
Parameters :
Returns :
boolean
more info is required |
changeCheckboxes |
changeCheckboxes()
|
Update the list of selected checkbox
Returns :
void
|
changeExpand |
changeExpand()
|
Update the list of selected checkbox
Returns :
void
|
changePaginationPager | ||||||||
changePaginationPager(params: )
|
||||||||
Update event from the Paginator Pager
Parameters :
Returns :
void
|
collapsePage |
collapsePage()
|
Collapses all definition entries to hid the flow diagrams on list page.
Returns :
void
|
countSelected |
countSelected()
|
Number of selected stream definitions
Returns :
number
|
createStream |
createStream()
|
Navigate to the create stream
Returns :
void
|
deploy | ||||||||
deploy(item: StreamDefinition)
|
||||||||
Route to stream deployment page.
Parameters :
Returns :
void
|
deploySelectedStreams |
deploySelectedStreams()
|
Starts the deploy process of multiple StreamDefinitions by opening a confirmation modal dialog.
Returns :
void
|
deployStreams | ||||||||
deployStreams(streamDefinitions: StreamDefinition[])
|
||||||||
Starts the deploy process of multiple StreamDefinitions by opening a confirmation modal dialog.
Parameters :
Returns :
void
|
destroy | ||||||||
destroy(item: StreamDefinition)
|
||||||||
Removes the StreamDefinition from the repository. Shows modal dialog prior to deletion to verify if user wants to destroy definition.
Parameters :
Returns :
void
|
destroySelectedStreams |
destroySelectedStreams()
|
Starts the destroy process of multiple StreamDefinitions by opening a confirmation modal dialog.
Returns :
void
|
destroyStreams | ||||||||
destroyStreams(streamDefinitions: StreamDefinition[])
|
||||||||
Starts the destroy the StreamDefinitions in parameter by opening a confirmation modal dialog.
Parameters :
Returns :
void
|
details | ||||||||
details(item: StreamDefinition)
|
||||||||
Route to StreamDefinition details page.
Parameters :
Returns :
void
|
expandPage |
expandPage()
|
Expands all definition entries to show flo diagram on list page.
Returns :
void
|
grafanaDashboard |
grafanaDashboard()
|
Navigate to the grafana Dashboard
Returns :
void
|
grafanaStreamDashboard | ||||||||
grafanaStreamDashboard(streamDefinition: StreamDefinition)
|
||||||||
Navigate to the grafana stream Dashboard
Parameters :
Returns :
void
|
loadStreamMetrics |
loadStreamMetrics()
|
Loads streams streamStatuses data
Returns :
void
|
metricsForStream | ||||||||
metricsForStream(name: string)
|
||||||||
Metrics for stream
Parameters :
Returns :
StreamStatuses
|
ngOnDestroy |
ngOnDestroy()
|
Close subscription
Returns :
void
|
ngOnInit |
ngOnInit()
|
Retrieves the StreamDefinitions to be displayed on the page.
Returns :
void
|
refresh |
refresh()
|
Initializes the streamDefinitions attribute with the results from Spring Cloud Data Flow server.
Returns :
void
|
registerApps |
registerApps()
|
Navigate to the register app
Returns :
void
|
search | ||||||||
search(params: ListDefaultParams)
|
||||||||
Run the search
Parameters :
Returns :
void
|
streamActions | ||||||||||||
streamActions(item: StreamDefinition, index: number)
|
||||||||||||
Row actions
Parameters :
Returns :
{}
|
streamsActions |
streamsActions()
|
Stream selected actions
Returns :
{}
|
toggleExpand | ||||||||
toggleExpand(index: )
|
||||||||
Toogle Expand
Parameters :
Returns :
void
|
undeploy | ||||||||
undeploy(item: StreamDefinition)
|
||||||||
Undeploys the StreamDefinition and displays toasty message after complete.
Parameters :
Returns :
void
|
undeploySelectedStreams |
undeploySelectedStreams()
|
Starts the undeploy process of multiple StreamDefinitions by opening a confirmation modal dialog.
Returns :
void
|
undeployStreams | ||||||||
undeployStreams(streamDefinitions: StreamDefinition[])
|
||||||||
Starts the undeploy process of multiple StreamDefinitions by opening a confirmation modal dialog.
Parameters :
Returns :
void
|
updateContext |
updateContext()
|
Write the context in the service.
Returns :
void
|
appsState$ |
appsState$:
|
Type : Observable<any>
|
Apps State |
context |
context:
|
Type : any
|
Storage context |
form |
form:
|
Type : any
|
Current forms value |
grafanaEnabled |
grafanaEnabled:
|
Default value : false
|
Featured Info |
grafanaEnabledSubscription |
grafanaEnabledSubscription:
|
Type : Subscription
|
Grafana Subscription |
itemsExpanded |
itemsExpanded:
|
Type : Array<string>
|
Contain a key application of each expanded application |
itemsSelected |
itemsSelected:
|
Type : Array<string>
|
Contain a key application of each selected application |
listBar |
listBar:
|
Type : ListBarComponent
|
Decorators : ViewChild
|
List Bar Component |
metricsSubscription |
metricsSubscription:
|
Type : Subscription
|
Metrics Subscription |
modal |
modal:
|
Type : BsModalRef
|
Modal reference |
Private ngUnsubscribe$ |
ngUnsubscribe$:
|
Type : Subject<any>
|
Unsubscribe |
noApplicationRegister |
noApplicationRegister:
|
Type : boolean
|
State of application register empty |
params |
params:
|
Type : StreamListParams
|
State of App List Params |
runtimeStreamStatusesSubscription |
runtimeStreamStatusesSubscription:
|
Type : Subscription
|
Runtime Statuses Subscription |
streamDefinitions |
streamDefinitions:
|
Type : Page<StreamDefinition>
|
Current page of Stream definitions |
Public streamsService |
streamsService:
|
Type : StreamsService
|
streamStatuses |
streamStatuses:
|
Type : StreamStatuses[]
|
Array of streamStatuses |
timeSubscription |
timeSubscription:
|
Type : Subscription
|
Time Subscription |
import { Component, OnInit, OnDestroy, ViewEncapsulation, ViewChild, NgZone, ChangeDetectorRef } from '@angular/core';
import { Page } from '../../shared/model';
import { StreamDefinition } from '../model/stream-definition';
import { StreamsService } from '../streams.service';
import { of, Subscription, timer } from 'rxjs';
import { StreamStatuses } from '../model/stream-metrics';
import { Router } from '@angular/router';
import { BsModalRef, BsModalService } from 'ngx-bootstrap';
import { StreamsDeployComponent } from '../streams-deploy/streams-deploy.component';
import { StreamsUndeployComponent } from '../streams-undeploy/streams-undeploy.component';
import { StreamsDestroyComponent } from '../streams-destroy/streams-destroy.component';
import { SortParams, OrderParams, ListDefaultParams } from '../../shared/components/shared.interface';
import { StreamListParams } from '../components/streams.interface';
import { mergeMap, takeUntil, map, finalize } from 'rxjs/operators';
import { AppsService } from '../../apps/apps.service';
import { AppRegistration } from '../../shared/model/app-registration.model';
import { NotificationService } from '../../shared/services/notification.service';
import { LoggerService } from '../../shared/services/logger.service';
import { AppError } from '../../shared/model/error.model';
import { ListBarComponent } from '../../shared/components/list/list-bar.component';
import { AuthService } from '../../auth/auth.service';
import { Observable, Subject } from 'rxjs';
import { SharedAboutService } from '../../shared/services/shared-about.service';
import { GrafanaService } from '../../shared/grafana/grafana.service';
import { BlockerService } from '../../shared/components/blocker/blocker.service';
@Component({
selector: 'app-streams',
templateUrl: './streams.component.html',
styleUrls: ['./styles.scss'],
encapsulation: ViewEncapsulation.None
})
/**
* Component that handles the listing and undeploy of stream definitions
* as well as the routing to other components for detail, deployment and
* creation of a {@link StreamDefinition}.
*
* @author Janne Valkealahti
* @author Gunnar Hillert
* @author Glenn Renfro
* @author Damien Vitrac
*/
export class StreamsComponent implements OnInit, OnDestroy {
/**
* Current page of Stream definitions
*/
streamDefinitions: Page<StreamDefinition>;
/**
* Unsubscribe
*/
private ngUnsubscribe$: Subject<any> = new Subject();
/**
* List Bar Component
*/
@ViewChild('listBar', { static: true })
listBar: ListBarComponent;
/**
* Metrics Subscription
*/
metricsSubscription: Subscription;
/**
* Array of streamStatuses
*/
streamStatuses: StreamStatuses[];
/**
* Modal reference
*/
modal: BsModalRef;
/**
* Current forms value
*/
form: any = {
q: '',
type: '',
checkboxes: [],
checkboxesExpand: []
};
/**
* State of App List Params
*/
params: StreamListParams = {
sort: 'name',
order: OrderParams.ASC,
page: 0,
size: 30,
q: ''
};
/**
* State of application register empty
*/
noApplicationRegister: boolean;
/**
* Contain a key application of each selected application
* @type {Array}
*/
itemsSelected: Array<string> = [];
/**
* Contain a key application of each expanded application
* @type {Array}
*/
itemsExpanded: Array<string> = [];
/**
* Storage context
*/
context: any;
/**
* Apps State
*/
appsState$: Observable<any>;
/**
* Grafana Subscription
*/
grafanaEnabledSubscription: Subscription;
/**
* Featured Info
*/
grafanaEnabled = false;
/**
* Runtime Statuses Subscription
*/
runtimeStreamStatusesSubscription: Subscription;
/**
* Time Subscription
*/
timeSubscription: Subscription;
/**
* Initialize component
*
* @param streamsService
* @param modalService
* @param appsService
* @param notificationService
* @param loggerService
* @param authService
* @param sharedAboutService
* @param grafanaService
* @param blockerService
* @param router
*/
constructor(public streamsService: StreamsService,
private modalService: BsModalService,
private appsService: AppsService,
private notificationService: NotificationService,
private loggerService: LoggerService,
private authService: AuthService,
private sharedAboutService: SharedAboutService,
private grafanaService: GrafanaService,
private blockerService: BlockerService,
private router: Router) {
}
/**
* Stream selected actions
*/
streamsActions() {
return [
{
id: 'deploy-streams',
icon: 'play',
action: 'deploySelected',
title: 'Deploy stream(s)',
hidden: !this.authService.securityInfo.canAccess(['ROLE_DEPLOY'])
},
{
id: 'undeploy-streams',
icon: 'pause',
action: 'undeploySelected',
title: 'Undeploy stream(s)',
hidden: !this.authService.securityInfo.canAccess(['ROLE_CREATE'])
},
{
id: 'destroy-streams',
icon: 'trash',
action: 'destroySelected',
title: 'Destroy stream(s)',
hidden: !this.authService.securityInfo.canAccess(['ROLE_DESTROY'])
},
];
}
/**
* Row actions
* @param {AppRegistration} item
* @param {number} index
*/
streamActions(item: StreamDefinition, index: number) {
return [
{
id: 'details-stream' + index,
action: 'details',
icon: 'info-circle',
title: 'Show details',
isDefault: true
},
{
id: 'grafana-stream' + index,
action: 'grafana',
icon: 'grafana',
custom: true,
title: 'Grafana Dashboard',
isDefault: true,
disabled: (item.status === 'undeployed'),
hidden: !this.grafanaEnabled
},
{
divider: true,
hidden: !this.authService.securityInfo.canAccess(['ROLE_CREATE', 'ROLE_DEPLOY', 'ROLE_DESTROY'])
},
{
id: 'deploy-stream' + index,
action: 'deploy',
icon: 'play',
title: 'Deploy stream',
isDefault: true,
hidden: !this.authService.securityInfo.canAccess(['ROLE_DEPLOY']) || (item.status !== 'undeployed')
},
{
id: 'update-stream' + index,
action: 'deploy',
icon: 'edit',
title: 'Update stream',
isDefault: true,
hidden: !this.authService.securityInfo.canAccess(['ROLE_MODIFY']) || (item.status === 'undeployed')
},
{
id: 'undeploy-stream' + index,
action: 'undeploy',
icon: 'pause',
title: 'Undeploy stream',
isDefault: !(item.status === 'undeployed'),
disabled: (item.status === 'undeployed'),
hidden: !this.authService.securityInfo.canAccess(['ROLE_CREATE'])
},
{
divider: true,
hidden: !this.authService.securityInfo.canAccess(['ROLE_DESTROY'])
},
{
id: 'destroy-stream' + index,
action: 'destroy',
icon: 'trash',
title: 'Destroy stream',
hidden: !this.authService.securityInfo.canAccess(['ROLE_DESTROY'])
},
];
}
/**
* Apply Action
* @param {string} action
* @param {any} args
*/
applyAction(action: string, args?: any) {
switch (action) {
case 'details':
this.details(args);
break;
case 'deploy':
this.deploy(args);
break;
case 'undeploy':
this.undeploy(args);
break;
case 'destroy':
this.destroy(args);
break;
case 'deploySelected':
this.deploySelectedStreams();
break;
case 'undeploySelected':
this.undeploySelectedStreams();
break;
case 'destroySelected':
this.destroySelectedStreams();
break;
case 'grafana':
this.grafanaStreamDashboard(args);
break;
}
}
/**
* Retrieves the {@link StreamDefinition}s to be displayed on the page.
*/
ngOnInit() {
this.context = this.streamsService.streamsContext;
this.params = { ...this.context };
this.form = { q: this.context.q, checkboxes: [], checkboxesExpand: [] };
this.itemsSelected = this.context.itemsSelected || [];
this.itemsExpanded = this.context.itemsExpanded || [];
this.grafanaEnabledSubscription = this.grafanaService.isAllowed().subscribe((active: boolean) => {
this.grafanaEnabled = active;
});
this.appsState$ = this.appsService.appsState();
this.refresh();
}
/**
* Close subscription
*/
ngOnDestroy() {
if (this.metricsSubscription) {
this.metricsSubscription.unsubscribe();
}
if (this.timeSubscription) {
this.timeSubscription.unsubscribe();
}
if (this.runtimeStreamStatusesSubscription) {
this.runtimeStreamStatusesSubscription.unsubscribe();
}
this.grafanaEnabledSubscription.unsubscribe();
this.ngUnsubscribe$.next();
this.ngUnsubscribe$.complete();
}
/**
* Initializes the streamDefinitions attribute with the results from Spring Cloud Data Flow server.
*/
refresh() {
this.loggerService.log('Loading Stream Definitions...', this.params);
this.streamsService
.getDefinitions(this.params)
.pipe(takeUntil(this.ngUnsubscribe$))
.pipe(
map((page: Page<StreamDefinition>) => {
this.form.checkboxes = page.items.map((stream) => {
return this.itemsSelected.indexOf(stream.name) > -1;
});
this.form.checkboxesExpand = page.items.map((stream) => {
return this.itemsExpanded.indexOf(stream.name) > -1;
});
return page;
}),
mergeMap(
val => this.appsService.getApps({
q: '', type: null, page: 0, size: 1, order: 'name', sort: OrderParams.ASC
}).pipe(map((val2) => {
return {
streams: val,
apps: val2,
};
})))
)
.subscribe((value: { streams: Page<StreamDefinition>, apps: Page<AppRegistration>, statuses: any }) => {
if (value.streams.items.length === 0 && this.params.page > 0) {
this.params.page = 0;
this.refresh();
return;
}
this.noApplicationRegister = !(value.apps.totalElements > 0);
this.streamDefinitions = value.streams;
this.changeExpand();
this.changeCheckboxes();
this.updateContext();
if (!this.timeSubscription) {
this.loadStreamMetrics();
this.timeSubscription = timer(0, 10 * 1000)
.subscribe(() => {
this.loadStreamMetrics();
});
}
},
error => {
this.notificationService.error(AppError.is(error) ? error.getMessage() : error);
});
}
/**
* Write the context in the service.
*/
updateContext() {
this.context.q = this.params.q;
this.context.sort = this.params.sort;
this.context.order = this.params.order;
this.context.page = this.params.page;
this.context.size = this.params.size;
this.context.itemsSelected = this.itemsSelected;
this.context.itemsExpanded = this.itemsExpanded;
}
/**
* Apply sort
* Triggered on column header click
*
* @param {SortParams} sort
*/
applySort(sort: SortParams) {
this.params.sort = sort.sort;
this.params.order = sort.order;
this.refresh();
}
/**
* Run the search
*/
search(params: ListDefaultParams) {
this.params.q = params.q;
this.params.page = 0;
this.refresh();
}
/**
* Update the list of selected checkbox
*/
changeCheckboxes() {
if (!this.streamDefinitions || (this.streamDefinitions.items.length !== this.form.checkboxes.length)) {
return;
}
const value: Array<string> = this.streamDefinitions.items.map((app, index) => {
if (this.form.checkboxes[index]) {
return app.name;
}
}).filter((a) => a != null);
this.itemsSelected = value;
this.updateContext();
}
/**
* Update the list of selected checkbox
*/
changeExpand() {
if (!this.streamDefinitions || (this.streamDefinitions.items.length !== this.form.checkboxesExpand.length)) {
return;
}
const value: Array<string> = this.streamDefinitions.items.map((app, index) => {
if (this.form.checkboxesExpand[index]) {
return app.name;
}
}).filter((a) => a != null);
this.itemsExpanded = value;
this.updateContext();
}
/**
* Loads streams streamStatuses data
*/
loadStreamMetrics() {
const streamNames = this.streamDefinitions && Array.isArray(this.streamDefinitions.items) ?
this.streamDefinitions.items
.filter(i => (i.status === 'deployed') || (i.status === 'deploying') || (i.status === 'partial'))
.map(s => s.name.toString())
: [];
if (streamNames.length) {
if (this.runtimeStreamStatusesSubscription) {
this.runtimeStreamStatusesSubscription.unsubscribe();
}
this.runtimeStreamStatusesSubscription = this.streamsService.getRuntimeStreamStatuses(streamNames)
.subscribe(metrics => {
this.streamStatuses = metrics;
});
} else {
this.streamStatuses = [];
}
}
/**
* Toogle Expand
*/
toggleExpand(index) {
this.form.checkboxesExpand[index] = !this.form.checkboxesExpand[index];
this.changeExpand();
}
/**
* Expands all definition entries to show flo diagram on list page.
*/
expandPage() {
this.loggerService.log('Expand all.');
this.form.checkboxesExpand = this.streamDefinitions.items.map(() => true);
this.changeExpand();
}
/**
* Collapses all definition entries to hid the flow diagrams on list page.
*/
collapsePage() {
this.loggerService.log('Collapse all.');
this.form.checkboxesExpand = this.streamDefinitions.items.map(() => false);
this.changeExpand();
}
/**
* Number of selected stream definitions
* @returns {number}
*/
countSelected(): number {
return this.form.checkboxes.filter((a) => a).length;
}
/**
* Update event from the Paginator Pager
* @param params
*/
changePaginationPager(params) {
this.params.page = params.page;
this.params.size = params.size;
this.updateContext();
this.refresh();
}
/**
* Route to {@link StreamDefinition} details page.
* @param item the stream definition to be displayed.
*/
details(item: StreamDefinition) {
this.router.navigate(['streams/definitions/' + item.name]);
}
/**
* Undeploys the {@link StreamDefinition} and displays toasty message after complete.
* @param item the stream definition to be undeployed.
*/
undeploy(item: StreamDefinition) {
this.blockerService.lock();
this.streamsService
.undeployDefinition(item)
.pipe(takeUntil(this.ngUnsubscribe$), finalize(() => this.blockerService.unlock()))
.subscribe(data => {
this.notificationService.success(`Successfully undeployed stream definition "${item.name}"`);
}, () => {
this.notificationService.error('An error occurred while undeploying Stream. ' +
'Please check the server logs for more details.');
});
}
/**
* Starts the undeploy process of multiple {@link StreamDefinition}s
* by opening a confirmation modal dialog.
*/
undeploySelectedStreams() {
const streamDefinitions = this.streamDefinitions.items
.filter((item) => this.itemsSelected.indexOf(item.name) > -1);
this.undeployStreams(streamDefinitions);
}
/**
* Route to stream deployment page.
* @param item the stream definition to be deployed.
*/
deploy(item: StreamDefinition) {
this.router.navigate(['streams/definitions/' + item.name + '/deploy']);
}
/**
* Starts the deploy process of multiple {@link StreamDefinition}s
* by opening a confirmation modal dialog.
*/
deploySelectedStreams() {
const streamDefinitions = this.streamDefinitions.items
.filter((item) => this.itemsSelected.indexOf(item.name) > -1)
.map(item => {
item.deploymentProperties = {};
return item;
});
if (streamDefinitions.length === 0) {
return;
}
this.deployStreams(streamDefinitions);
}
/**
* Removes the {@link StreamDefinition} from the repository. Shows modal dialog
* prior to deletion to verify if user wants to destroy definition.
* @param item the stream definition to be removed.
*/
destroy(item: StreamDefinition) {
this.destroyStreams([item]);
}
/**
* Starts the destroy process of multiple {@link StreamDefinition}s
* by opening a confirmation modal dialog.
*/
destroySelectedStreams() {
const streamDefinitions = this.streamDefinitions.items
.filter((item) => this.itemsSelected.indexOf(item.name) > -1);
this.destroyStreams(streamDefinitions);
}
/**
* Starts the destroy the {@link StreamDefinition}s in parameter
* by opening a confirmation modal dialog.
* @param {StreamDefinition[]} streamDefinitions
*/
destroyStreams(streamDefinitions: StreamDefinition[]) {
if (streamDefinitions.length === 0) {
return;
}
this.loggerService.log(`Destroy ${streamDefinitions} stream definition(s).`, streamDefinitions);
const className = streamDefinitions.length > 1 ? 'modal-lg' : 'modal-md';
this.modal = this.modalService.show(StreamsDestroyComponent, { class: className });
this.modal.content.open({ streamDefinitions: streamDefinitions }).subscribe(() => {
if (this.streamDefinitions.items.length === 0 &&
this.streamDefinitions.pageNumber > 0) {
this.streamDefinitions.pageNumber = this.streamDefinitions.pageNumber - 1;
}
this.refresh();
});
}
/**
* Starts the deploy process of multiple {@link StreamDefinition}s
* by opening a confirmation modal dialog.
*/
deployStreams(streamDefinitions: StreamDefinition[]) {
if (streamDefinitions.length === 0) {
return;
}
if (streamDefinitions.length === 1) {
this.router.navigate(['streams/definitions/' + streamDefinitions[0].name + '/deploy']);
} else {
this.loggerService.log(`Deploy ${streamDefinitions.length} stream definition(s).`, streamDefinitions);
this.modal = this.modalService.show(StreamsDeployComponent, { class: 'modal-xl' });
this.modal.content.open({ streamDefinitions: streamDefinitions }).subscribe(() => {
this.refresh();
});
}
}
/**
* Starts the undeploy process of multiple {@link StreamDefinition}s
* by opening a confirmation modal dialog.
*/
undeployStreams(streamDefinitions: StreamDefinition[]) {
if (streamDefinitions.length === 0) {
return;
}
this.loggerService.log(`Undeploy ${streamDefinitions.length} stream definition(s).`, streamDefinitions);
this.modal = this.modalService.show(StreamsUndeployComponent, { class: 'modal-lg' });
this.modal.content.open({ streamDefinitions: streamDefinitions }).subscribe(() => {
this.refresh();
});
}
/**
* Metrics for stream
* @param {string} name
* @returns {StreamStatuses}
*/
metricsForStream(name: string): StreamStatuses {
if (Array.isArray(this.streamStatuses)) {
return this.streamStatuses.find(m => m.name === name);
}
}
/**
* Determine show deployment info
*
* @param {StreamDefinition} item
* @returns {boolean} more info is required
*/
canShowDeploymentInfo(item: StreamDefinition) {
return item.status === 'deployed'
|| item.status === 'deploying'
|| item.status === 'failed'
|| item.status === 'incomplete';
}
/**
* Navigate to the create stream
*/
createStream() {
this.router.navigate(['/streams/create']);
}
/**
* Navigate to the register app
*/
registerApps() {
this.router.navigate(['/apps/add']);
}
/**
* Navigate to the grafana Dashboard
*/
grafanaDashboard() {
this.grafanaService.getDashboardStreams().subscribe((url: string) => {
window.open(url);
});
}
/**
* Navigate to the grafana stream Dashboard
* @param streamDefinition
*/
grafanaStreamDashboard(streamDefinition: StreamDefinition) {
this.grafanaService.getDashboardStream(streamDefinition).subscribe((url: string) => {
window.open(url);
});
}
}
<app-page *ngIf="streamDefinitions">
<app-page-head>
<app-page-head-title><strong>Streams</strong></app-page-head-title>
<app-page-head-actions [dataflowAppRoles]="['ROLE_CREATE']">
<ng-container *ngIf="appsState$ | async as appsState;">
<button class="btn btn-primary btn-fa" (click)="createStream()" *ngIf="appsState.streams > 0">
<span class="fa fa-plus"></span>
Create stream(s)
</button>
<button name="stream-grafana" type="button" *ngIf="grafanaEnabled"
(click)="grafanaDashboard()" class="btn btn-primary btn-fa" title="Grafana Dashboard">
<span class="icon-custom icon-custom-grafana white"></span>
Grafana Dashboard
</button>
</ng-container>
</app-page-head-actions>
</app-page-head>
<div dataflowLayoutType type="full">
<p>This section lists all the stream definitions and provides the ability to deploy/undeploy or destroy streams.</p>
<app-list-bar [params]="params" [page]="streamDefinitions" [countSelected]="countSelected()" #listBar
(refresh)="refresh()" (search)="search($event)" [actions]="streamsActions()"
(action)="applyAction($event.action)">
</app-list-bar>
<table *ngIf="streamDefinitions?.items && streamDefinitions.items.length > 0"
class="table table-hover table-checkbox" id="streamDefinitionsTable">
<thead>
<tr>
<th style="width: 30px" [dataflowAppRoles]="['ROLE_CREATE']">
<app-master-checkbox (change)="changeCheckboxes()" *ngIf="form?.checkboxes"
[items]="form.checkboxes"></app-master-checkbox>
</th>
<th style="width: 70px">
<app-sort id="sort-name" (change)="applySort($event)" [value]="'name'" [sort]="params">
Name
</app-sort>
<th>
<div class="head-dsl">
<div class="dropdown" dropdown>
<a dropdownToggle class="btn-dropdown" data-toggle="dropdown">
<span class="fa fa-chevron-down"></span>
<span class="fa fa-chevron-right"></span>
</a>
<ul *dropdownMenu class="dropdown-menu">
<li><a style="cursor: pointer" (click)="expandPage()">Expand All</a></li>
<li><a style="cursor: pointer" (click)="collapsePage()">Collapse All</a></li>
</ul>
</div>
<app-sort id="sort-dsl" (change)="applySort($event)" [value]="'dslText'" [sort]="params">
Definitions
</app-sort>
</div>
</th>
<th nowrap="" style="width: 120px">
Status
<a #childPopover="bs-popover" [popover]="popTemplate" placement="left" [outsideClick]="true"
title="Available Deployment Statuses" style="cursor: pointer">
<span class="fa fa-question-circle"></span></a>
</th>
<th> </th>
</tr>
</thead>
<tbody>
<ng-container
*ngFor="let item of streamDefinitions.items | paginate: streamDefinitions.getPaginationInstance(); index as i">
<tr>
<td class="cell-checkbox" [dataflowAppRoles]="['ROLE_CREATE']">
<input [dataflowAppRoles]="['ROLE_CREATE']" type="checkbox" (change)="changeCheckboxes()"
[(ngModel)]="form.checkboxes[i]"/>
</td>
<td>
<a style="cursor:pointer" (click)="details(item)">{{ item.name }}</a>
</td>
<td>
<a (click)="toggleExpand(i)" class="link-expand">
<span *ngIf="form.checkboxesExpand[i]" class="fa fa-chevron-down" tooltip="Hide graph" delay="500"></span>
<span *ngIf="!form.checkboxesExpand[i]" class="fa fa-chevron-right" tooltip="Show graph"
delay="500"></span>
<app-stream-dsl>{{ item.dslText | truncate: 120 }}</app-stream-dsl>
</a>
</td>
<td *ngIf="canShowDeploymentInfo(item); else deployment_status_only_content">
<a href="" class="stream-info-toggle" (click)="false" [popover]="stream_info" placement="left"
triggers="focus"
containerClass="deployment-info-popup">
<span class="ico fa fa-info-circle"></span>
<app-stream-status [streamDefinition]="item"></app-stream-status>
</a>
</td>
<ng-template #deployment_status_only_content>
<td>
<app-stream-status [streamDefinition]="item"></app-stream-status>
</td>
</ng-template>
<ng-template #stream_info>
<app-stream-deployment-properties-info [streamDefinition]="item"></app-stream-deployment-properties-info>
</ng-template>
<td class="table-actions" width="10px" nowrap="">
<app-list-row-actions [actions]="streamActions(item, i)" (action)="applyAction($event.action, $event.args)"
[item]="item">
</app-list-row-actions>
</td>
</tr>
<tr *ngIf="form.checkboxesExpand[i]">
<td colspan="5" class="graph" style="padding:0">
<app-stream-graph-definition [stream]="item" [metrics]="metricsForStream(item.name)">
</app-stream-graph-definition>
</td>
</tr>
</ng-container>
</tbody>
</table>
<app-list-pagination [page]="streamDefinitions" [params]="params" (changed)="changePaginationPager($event)"
[item]="'stream definition'" [items]="'stream definitions'">
</app-list-pagination>
<app-list-empty [page]="streamDefinitions" [filters]="[params.q]">
<p>There is <strong>no stream registered</strong>, yet.</p>
<div *ngIf="appsState$ | async as appsState">
<p *ngIf="appsState.streams > 0" [dataflowAppRoles]="['ROLE_CREATE']">
You can <a (click)="createStream()">Create Streams(s)</a> or <a (click)="refresh()">Refresh</a> the page
</p>
<p *ngIf="appsState.streams == 0" [dataflowAppRoles]="['ROLE_CREATE']">
To create stream(s), you have to <a (click)="registerApps()">register Apps</a> first.<br/>
You can <a (click)="refresh()">Refresh</a> the page.
</p>
</div>
</app-list-empty>
<app-list-no-result [page]="streamDefinitions" [filters]="[params.q]">
<p>
No results found for
<strong>'{{ params.q }}'</strong>
</p>
<p>
You can <a (click)="listBar.clearSearch()">Clear the search</a> or <a (click)="refresh()">Refresh</a> the page.
</p>
</app-list-no-result>
<ng-template #popTemplate>
<div class="status-help-content">
<table class="table-condensed status-help-content-table">
<tbody>
<tr>
<td>
<app-stream-status [streamDefinition]="{ status : 'deploying' }"></app-stream-status>
</td>
<td>Deployment has been initiated</td>
</tr>
<tr>
<td>
<app-stream-status [streamDefinition]="{ status : 'deployed' }"></app-stream-status>
</td>
<td>Fully deployed based on each of the stream's apps' count properties</td>
</tr>
<tr>
<td>
<app-stream-status [streamDefinition]="{ status : 'incomplete' }"></app-stream-status>
</td>
<td>At least 1 of each app, but 1 or more of them not at requested capacity</td>
</tr>
<tr>
<td>
<app-stream-status [streamDefinition]="{ status : 'failed' }"></app-stream-status>
</td>
<td>1 or more of the apps does not have even a single instance deployed</td>
</tr>
<tr>
<td>
<app-stream-status [streamDefinition]="{ status : 'undeployed' }"></app-stream-status>
</td>
<td>Intentionally undeployed, or created but not yet deployed</td>
</tr>
</tbody>
</table>
</div>
</ng-template>
</div>
</app-page>
<div *ngIf="!streamDefinitions">
<app-loader></app-loader>
</div>