File
Implements
Methods
Protected
fetchResources
|
fetchResources()
|
|
|
onSelect
|
onSelect(undefined)
|
|
|
headerHeight
|
Default value : Settings.tableHeaderHeight
|
|
isForInstance
|
Default value : false
|
|
isLoading
|
Default value : true
|
|
rowHeight
|
Default value : Settings.tableRowHeight
|
|
sorts
|
Type : []
|
Default value : [
{ prop: 'alive', dir: 'asc' },
{ prop: 'name', dir: 'asc' },
]
|
|
table
|
Type : DatatableComponent
|
Decorators :
@ViewChild('resourcesTable', {static: false})
|
|
import { Component, OnInit, ViewChild } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import * as _ from 'lodash';
import { Settings } from '../../core/settings';
import { Resource } from '../shared/resource.model';
import { ResourceService } from '../shared/resource.service';
import { WorkflowService } from '../../workflow/shared/workflow.service';
import { HelperService } from '../../shared/helper.service';
import { DatatableComponent } from '@swimlane/ngx-datatable';
@Component({
selector: 'hi-resource-list',
templateUrl: './resource-list.component.html',
styleUrls: ['./resource-list.component.scss'],
providers: [WorkflowService],
})
export class ResourceListComponent implements OnInit {
@ViewChild('resourcesTable', { static: false })
table: DatatableComponent;
isForInstance = false;
headerHeight = Settings.tableHeaderHeight;
rowHeight = Settings.tableRowHeight;
resources: Resource[];
isLoading = true;
clusterName: string;
instanceName: string;
sorts = [
{ prop: 'alive', dir: 'asc' },
{ prop: 'name', dir: 'asc' },
];
constructor(
private router: Router,
private route: ActivatedRoute,
private service: ResourceService,
private workflowService: WorkflowService,
protected helper: HelperService
) {}
ngOnInit() {
if (this.route.parent) {
if (this.route.snapshot.data.forInstance) {
this.isForInstance = true;
this.isLoading = true;
this.clusterName = this.route.parent.snapshot.params.cluster_name;
this.instanceName = this.route.parent.snapshot.params.instance_name;
this.service
.getAllOnInstance(this.clusterName, this.instanceName)
.subscribe(
(resources) => (this.resources = resources),
(error) => console.log(error),
() => (this.isLoading = false)
);
} else {
this.route.parent.params.pipe(map((p) => p.name)).subscribe((name) => {
this.clusterName = name;
this.fetchResources();
});
}
}
}
// since resource list contains also workflows and jobs
// need to subtract them from original resource list
// to obtain all jobs list, need to go through every workflow
// and perform get request for each.
// However, it has huge performance issue when there are thousands of
// workflows. We are using a smart way here: to remove resources whose
// prefix is a workflow name
protected fetchResources() {
this.isLoading = true;
this.resources = null;
this.workflowService.getAll(this.clusterName).subscribe(
(workflows) => {
this.service.getAll(this.clusterName).subscribe(
(result) => {
this.resources = _.differenceWith(
result,
workflows,
(resource: Resource, prefix: string) =>
_.startsWith(resource.name, prefix)
);
},
(error) => this.helper.showError(error),
() => (this.isLoading = false)
);
},
(error) => this.helper.showError(error)
);
}
onSelect({ selected }) {
const row = selected[0];
if (this.isForInstance) {
this.table.rowDetail.toggleExpandRow(row);
} else {
this.router.navigate([row.name], { relativeTo: this.route });
}
}
}
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<section>
<ngx-datatable
#resourcesTable
class="material"
[headerHeight]="headerHeight"
[rowHeight]="rowHeight"
columnMode="force"
[footerHeight]="rowHeight"
[rows]="resources"
selectionType="single"
[sorts]="sorts"
[loadingIndicator]="isLoading"
(select)="onSelect($event)"
>
<ngx-datatable-column
*ngIf="!isForInstance"
name="Status"
prop="alive"
[width]="88"
[resizeable]="false"
[draggable]="false"
[canAutoResize]="false"
>
<ng-template let-value="value" ngx-datatable-cell-template>
<mat-icon *ngIf="value" color="primary">lens</mat-icon>
<mat-icon
*ngIf="!value"
color="warn"
matTooltip="The resource is offline."
>panorama_fish_eye</mat-icon
>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column
*ngIf="isForInstance"
[width]="50"
[resizeable]="false"
[sortable]="false"
[draggable]="false"
[canAutoResize]="false"
>
<ng-template let-expanded="expanded" ngx-datatable-cell-template>
<mat-icon>{{ expanded ? 'expand_more' : 'chevron_right' }}</mat-icon>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Name"></ngx-datatable-column>
<ngx-datatable-row-detail rowHeight="auto">
<ng-template let-row="row" ngx-datatable-row-detail-template>
<hi-resource-detail-for-instance
[clusterName]="clusterName"
[instanceName]="instanceName"
[resourceName]="row.name"
>
</hi-resource-detail-for-instance>
</ng-template>
</ngx-datatable-row-detail>
</ngx-datatable>
</section>
Legend
Html element with directive