Skip to content

Instantly share code, notes, and snippets.

@icfantv
Created July 28, 2016 22:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save icfantv/5bba22e908ef3804a9af9771459c29f6 to your computer and use it in GitHub Desktop.
Save icfantv/5bba22e908ef3804a9af9771459c29f6 to your computer and use it in GitHub Desktop.
NG2 List/Component
<h1>Export Records</h1>
<div *ngIf="exports.length === 0">
This system has no export records created.
</div>
<div *ngIf="exports.length > 0">
<table class="table table-fixedheader export-grid">
<thead>
<tr>
<th *ngFor="let header of headers; let i = index" [ngClass]="columnWidths[i]">
<div class="no-select"
[title]="header.name"
[ngClass]="{'no-click': !header.predicate, 'pointer': header.predicate}"
(click)="resort(header.predicate)">
{{ header.name }}
<i [ngClass]="getHeaderSortIconClass(header)"></i>
</div>
</th>
</tr>
</thead>
<tbody class="webkit-scrollbar-fix">
<tr *ngFor="let item of exports" [ngClass]="getTypeClass(item)">
<td [ngClass]="columnWidths[0]">
<a href="#/exports/export/{{ item.id }}">
<i class="fa fa-search"></i>
</a>
</td>
<td [ngClass]="columnWidths[1]" [title]="item.type" [innerText]="item.type"></td>
<td [ngClass]="columnWidths[2]" [title]="item.op" [innerText]="item.op"></td>
<td [ngClass]="columnWidths[3]" [title]="item.node || '-'" [innerText]="item.node || '-'"></td>
<td [ngClass]="columnWidths[4]" [title]="item.snapshotCount | number" [innerText]="item.snapshotCount | number"></td>
<td [ngClass]="columnWidths[5]" [title]="item.startedAt | date:'medium'" [innerText]="item.startedAt | date:'medium'"></td>
<td [ngClass]="columnWidths[6]">
<div class="progress progress-bar-grid">
<div class="progress-bar progress-bar-{{getTypeClass(item)}}"
role="progressbar"
aria-valuemin="0"
aria-valuemax="100"
[style.width.%]="item.percentComplete">
{{ item.percentComplete }}%
</div>
</div>
</td>
</tr>
</tbody>
</table>
<div>
<span class="text-bold">Total Export Records:</span> {{ exports.length | number }}
</div>
</div>
import * as _isEqual from 'lodash/isEqual';
import {Component, OnDestroy, OnInit} from '@angular/core';
import {Observable, Subscription} from 'rxjs/Rx';
import 'rxjs/add/operator/mergeMap';
import {LexiOrderByPipe} from '../../common/pipes/LexiOrderByPipe';
import {ExportStatus, IExportRecord} from '../models';
import {ExportService} from '../services';
interface IColumnHeader {
name: string;
predicate?: Array<string>;
}
@Component({
providers: [ExportService],
selector: 'export-list-component',
template: require('!!html!./ExportListComponent.html')
})
export class ExportListComponent implements OnDestroy, OnInit {
private subscription: Subscription;
public loading = true;
public predicate: Array<string> = ['startedAt'];
public reverse = true;
public exports: Array<IExportRecord> = [];
public headers: Array<IColumnHeader> = [
{
name: 'Details'
},
{
name: 'Type',
predicate: ['type', 'startedAt']
},
{
name: 'Operation',
predicate: ['op', 'startedAt']
},
{
name: 'Node',
predicate: ['node', 'startedAt']
},
{
name: 'Snapshot Record Count',
predicate: ['snapshotCount', 'startedAt']
},
{
name: 'Started At',
predicate: ['startedAt']
},
{
name: 'Progress & Status'
}
];
public columnWidths: Array<string> = [
'col-w-5',
'col-w-10',
'col-w-10',
'col-w-20',
'col-w-15',
'col-w-15',
'col-w-25'
];
constructor(private service: ExportService) {}
public getHeaderSortIconClass(header: IColumnHeader): string {
let result = '';
if (header.predicate) {
if (this.isEqual(this.predicate, header.predicate)) {
if (this.reverse) {
result = 'fa fa-caret-up';
}
else {
result = 'fa fa-caret-down';
}
}
else {
result = 'fa fa-sort';
}
}
return result;
}
// noinspection JSMethodCanBeStatic
public getTypeClass(_export: IExportRecord): string {
let type: string;
switch (_export.status) {
case ExportStatus.SUCCESS:
type = 'success';
break;
case ExportStatus.WARN:
type = 'warning';
break;
case ExportStatus.ERROR:
type = 'danger';
break;
default:
type = 'info';
}
return type;
}
public resort(sortBy: Array<string> = this.predicate) {
if (this.predicate) {
if (this.isEqual(this.predicate, sortBy)) {
this.reverse = !this.reverse;
}
else {
this.predicate = sortBy;
this.reverse = false;
}
}
this.exports =
LexiOrderByPipe.INSTANCE.transform(this.exports,
this.predicate.map((item: string) => `${this.reverse ? '-' : '+'}${item}`));
}
// noinspection JSMethodCanBeStatic
public isEqual(first: Array<string>, second: Array<string>) {
return _isEqual(first, second);
}
// noinspection JSUnusedGlobalSymbols
ngOnInit() {
const poller: Observable<Array<IExportRecord>> =
Observable.timer(0, 10000).flatMap(() => this.service.getAll());
this.subscription = poller.subscribe((exports: Array<IExportRecord>) => {
this.exports =
LexiOrderByPipe.INSTANCE.transform(exports,
this.predicate.map((item: string) => `${this.reverse ? '-' : '+'}${item}`));
this.loading = false;
});
}
// noinspection JSUnusedGlobalSymbols
ngOnDestroy() {
if (this.subscription && !this.subscription.isUnsubscribed) {
this.subscription.unsubscribe();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment