Selected Column Filter Incomplete

Selected Column Filter Incomplete
pull/1127/head
ShahanaFarooqui 2 years ago
parent 211b6fdca4
commit 3b8ca9177a

@ -29,7 +29,7 @@
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let hop">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{hop?.id}}</span>
</div>
</td>
@ -37,7 +37,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let hop">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{hop?.alias}}</span>
</div>
</td>

@ -51,11 +51,16 @@
<fa-icon [icon]="faUsers" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Liquidity Providing Peers</span>
</div>
<mat-form-field fxFlex="30">
<div fxLayout="row" fxLayoutAlign="start start">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</div>
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -63,7 +68,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let lqNode">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" fxLayoutAlign="start center" class="ellipsis-child">
{{lqNode?.alias}}
<mat-chip-list class="ml-half" aria-label="Address Types">
@ -78,7 +83,7 @@
<ng-container matColumnDef="nodeid">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Node ID</th>
<td mat-cell *matCellDef="let lqNode">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{lqNode?.nodeid}}</span>
</div>
</td>

@ -10,7 +10,7 @@ import { faBullhorn, faExclamationTriangle, faUsers } from '@fortawesome/free-so
import { DataService } from '../../../shared/services/data.service';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
import { AlertTypeEnum, APICallStatusEnum, DataTypeEnum, getPaginatorLabel, PAGE_SIZE, PAGE_SIZE_OPTIONS, ScreenSizeEnum, NODE_FEATURES_CLN, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { AlertTypeEnum, APICallStatusEnum, DataTypeEnum, getPaginatorLabel, PAGE_SIZE, PAGE_SIZE_OPTIONS, ScreenSizeEnum, NODE_FEATURES_CLN, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLN_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { GetInfo, LookupNode } from '../../../shared/models/clnModels';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { openAlert, openConfirmation } from '../../../store/rtl.actions';
@ -20,7 +20,8 @@ import { RTLEffects } from '../../../store/rtl.effects';
import { CLNOpenLiquidityChannelComponent } from '../open-liquidity-channel-modal/open-liquidity-channel-modal.component';
import { clnPageSettings, nodeInfoAndNodeSettingsAndBalance } from '../../store/cln.selector';
import { DecimalPipe } from '@angular/common';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-liquidity-ads-list',
@ -34,6 +35,8 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'liquidity_ads';
public tableSetting: TableSetting = { tableId: 'liquidity_ads', recordsPerPage: PAGE_SIZE, sortBy: 'channel_opening_fee', sortOrder: SortOrderEnum.ASCENDING };
@ -61,7 +64,7 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private dataService: DataService, private commonService: CommonService, private rtlEffects: RTLEffects, private decimalPipe: DecimalPipe) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private dataService: DataService, private commonService: CommonService, private rtlEffects: RTLEffects, private decimalPipe: DecimalPipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.askTooltipMsg = 'Specify the liquidity requirements for your node: \n 1. Channel Amount - Amount in Sats you need on the channel opened to your node \n 2. Channel opening fee rate - Rate in Sats/vByte that you are willing to pay to open the channel to you';
this.nodesTooltipMsg = 'These nodes are advertising their liquidity offering on the network.\nYou should pay attention to the following aspects to evaluate each node offer: \n- The total bitcoin deployed on the node, the more the better\n';
this.nodesTooltipMsg = this.nodesTooltipMsg + '- The number of channels open on the node, the more the better' +
@ -135,11 +138,12 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
this.liquidityNodes.filter = this.selFilter.trim().toLowerCase();
}
loadLiqNodesTable(liqNodes: LookupNode[]) {
this.liquidityNodes = new MatTableDataSource<LookupNode>([...liqNodes]);
this.liquidityNodes.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.liquidityNodes.sort = this.sort;
this.liquidityNodes.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.liquidityNodes.filterPredicate = (node: LookupNode, fltr: string) => {
const newNode = ((node.alias) ? node.alias.toLocaleLowerCase() : '') + (node.channel_opening_fee ? node.channel_opening_fee + ' Sats' : '') +
(node.option_will_fund?.lease_fee_base_msat ? (node.option_will_fund?.lease_fee_base_msat / 1000) + ' Sats' : '') + (node.option_will_fund?.lease_fee_basis ? (this.decimalPipe.transform(node.option_will_fund?.lease_fee_basis / 100, '1.2-2') + '%') : '') +
@ -147,9 +151,40 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
(node.address_types ? node.address_types.reduce((acc, curr) => acc + (curr === 'tor' ? ' tor' : curr === 'ipv' ? ' clearnet' : (' ' + curr.toLowerCase())), '') : '');
return newNode.includes(fltr);
};
// this.liquidityNodes.filterPredicate = (rowData: LookupNode, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadLiqNodesTable(liqNodes: LookupNode[]) {
this.liquidityNodes = new MatTableDataSource<LookupNode>([...liqNodes]);
this.liquidityNodes.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.liquidityNodes.sort = this.sort;
this.liquidityNodes.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.setFilterPredicate();
this.applyFilter();
this.liquidityNodes.paginator = this.paginator;
// this.liquidityNodes.filterPredicate = (node: LookupNode, fltr: string) => node.channel_count >= this.channel_count && node.node_capacity >= this.node_capacity;
// this.liquidityNodes.filterPredicate = (rowData: LookupNode, fltr: string) => rowData.channel_count >= this.channel_count && rowData.node_capacity >= this.node_capacity;
// this.onFilter();
}

@ -1,9 +1,16 @@
<div fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100" class="padding-gap-x-large">
<div fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70" fxLayoutAlign="start start" fxLayoutAlign.gt-sm="start center"></div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start start">
<div [perfectScrollbar] class="table-container" fxFlex="100">
@ -26,7 +33,7 @@
<ng-container matColumnDef="txid">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Transaction ID</th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{utxo.txid}}</span>
</span>
</td>
@ -34,7 +41,7 @@
<ng-container matColumnDef="address">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Address</th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{utxo.address}}</span>
</span>
</td>
@ -42,7 +49,7 @@
<ng-container matColumnDef="scriptpubkey">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Script Pubkey</th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{utxo.scriptpubkey}}</span>
</span>
</td>

@ -8,7 +8,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { UTXO } from '../../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLN_PAGE_DEFS } from '../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../../shared/services/logger.service';
import { CommonService } from '../../../../shared/services/common.service';
@ -16,7 +16,8 @@ import { CommonService } from '../../../../shared/services/common.service';
import { RTLState } from '../../../../store/rtl.state';
import { openAlert } from '../../../../store/rtl.actions';
import { clnPageSettings, utxos } from '../../../store/cln.selector';
import { PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-on-chain-utxos',
@ -32,6 +33,8 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
@Input() numDustUTXOs = 0;
@Input() isDustUTXO = false;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'on_chain';
public tableSetting: TableSetting = { tableId: 'utxos', recordsPerPage: PAGE_SIZE, sortBy: 'status', sortOrder: SortOrderEnum.DESCENDING };
@ -48,7 +51,7 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private router: Router) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private router: Router, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -100,6 +103,38 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
this.listUTXOs.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.listUTXOs.filterPredicate = (utxo: UTXO, fltr: string) => JSON.stringify(utxo).toLowerCase().includes(fltr);
// this.listUTXOs.filterPredicate = (rowData: UTXO, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
onUTXOClick(selUtxo: UTXO, event: any) {
const reorderedUTXO = [
[{ key: 'txid', value: selUtxo.txid, title: 'Transaction ID', width: 100 }],
@ -125,8 +160,8 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
this.listUTXOs.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.listUTXOs.sort = this.sort;
this.listUTXOs.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.listUTXOs.filterPredicate = (utxo: UTXO, fltr: string) => JSON.stringify(utxo).toLowerCase().includes(fltr);
this.listUTXOs.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.listUTXOs);
}

@ -1,9 +1,16 @@
<div fxLayout="column">
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<div [perfectScrollbar] fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100">
@ -18,7 +25,7 @@
<ng-container matColumnDef="short_channel_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Short Channel ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.short_channel_id}}</span>
</div>
</td>
@ -26,7 +33,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.alias}}</span>
</div>
</td>
@ -34,7 +41,7 @@
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.id}}</span>
</div>
</td>
@ -42,7 +49,7 @@
<ng-container matColumnDef="channel_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.channel_id}}</span>
</div>
</td>
@ -50,7 +57,7 @@
<ng-container matColumnDef="funding_txid">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Funding Transaction ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.funding_txid}}</span>
</div>
</td>

@ -9,7 +9,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Channel, GetInfo, ChannelEdge, Balance } from '../../../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, FEE_RATE_TYPES, APICallStatusEnum, UI_MESSAGES, CLN_DEFAULT_PAGE_SETTINGS, SortOrderEnum } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, FEE_RATE_TYPES, APICallStatusEnum, UI_MESSAGES, CLN_DEFAULT_PAGE_SETTINGS, SortOrderEnum, CLN_PAGE_DEFS } from '../../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { CommonService } from '../../../../../shared/services/common.service';
@ -22,7 +22,8 @@ import { openAlert, openConfirmation } from '../../../../../store/rtl.actions';
import { RTLState } from '../../../../../store/rtl.state';
import { channelLookup, closeChannel, updateChannel } from '../../../../store/cln.actions';
import { channels, clnPageSettings, nodeInfoAndBalanceAndNumPeers } from '../../../../store/cln.selector';
import { PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-channel-open-table',
@ -38,6 +39,8 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faEye = faEye;
public faEyeSlash = faEyeSlash;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'open_channels', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };
@ -59,7 +62,7 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private clnEffects: CLNEffects, private commonService: CommonService, private router: Router) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private clnEffects: CLNEffects, private commonService: CommonService, private router: Router, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
this.selFilter = this.router?.getCurrentNavigation()?.extras?.state?.filter ? this.router?.getCurrentNavigation()?.extras?.state?.filter : '';
}
@ -251,10 +254,6 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
});
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
onChannelClick(selChannel: Channel, event: any) {
this.store.dispatch(openAlert({
payload: {
@ -267,12 +266,16 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
}));
}
loadChannelsTable(mychannels) {
// mychannels.sort((a, b) => ((a.active === b.active) ? 0 : ((b.active) ? 1 : -1)));
this.channels = new MatTableDataSource<Channel>([...mychannels]);
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.channels.filterPredicate = (channel: Channel, fltr: string) => {
const newChannel = ((channel.connected) ? 'connected' : 'disconnected') + (channel.channel_id ? channel.channel_id.toLowerCase() : '') +
(channel.short_channel_id ? channel.short_channel_id.toLowerCase() : '') + (channel.id ? channel.id.toLowerCase() : '') + (channel.alias ? channel.alias.toLowerCase() : '') +
@ -282,7 +285,38 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
(channel.our_channel_reserve_satoshis ? channel.our_channel_reserve_satoshis : '') + (channel.spendable_msatoshi ? channel.spendable_msatoshi : '');
return newChannel.includes(fltr);
};
// this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadChannelsTable(mychannels) {
this.channels = new MatTableDataSource<Channel>([...mychannels]);
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.channels.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.channels);
}

@ -1,9 +1,16 @@
<div fxLayout="column">
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<div [perfectScrollbar] fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100">
@ -18,7 +25,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.alias}}</span>
</div>
</td>
@ -26,7 +33,7 @@
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.id}}</span>
</div>
</td>
@ -34,7 +41,7 @@
<ng-container matColumnDef="channel_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.channel_id}}</span>
</div>
</td>
@ -42,7 +49,7 @@
<ng-container matColumnDef="funding_txid">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Funding Transaction ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.funding_txid}}</span>
</div>
</td>
@ -53,7 +60,7 @@
</ng-container>
<ng-container matColumnDef="state">
<th mat-header-cell *matHeaderCellDef mat-sort-header>State</th>
<td mat-cell *matCellDef="let channel" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">{{CLNChannelPendingState[channel?.state]}}</td>
<td mat-cell *matCellDef="let channel" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">{{CLNChannelPendingState[channel?.state]}}</td>
</ng-container>
<ng-container matColumnDef="our_channel_reserve_satoshis">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Local Reserve (Sats)</th>

@ -8,7 +8,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
import { GetInfo, Channel, Balance } from '../../../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, AlertTypeEnum, APICallStatusEnum, CLNChannelPendingState, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, AlertTypeEnum, APICallStatusEnum, CLNChannelPendingState, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLN_PAGE_DEFS } from '../../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { CommonService } from '../../../../../shared/services/common.service';
@ -20,7 +20,8 @@ import { openAlert, openConfirmation } from '../../../../../store/rtl.actions';
import { RTLState } from '../../../../../store/rtl.state';
import { closeChannel } from '../../../../store/cln.actions';
import { channels, clnPageSettings, nodeInfoAndBalanceAndNumPeers } from '../../../../store/cln.selector';
import { PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-channel-pending-table',
@ -36,6 +37,8 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faEye = faEye;
public faEyeSlash = faEyeSlash;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'pending_inactive_channels', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };
@ -59,7 +62,7 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -115,10 +118,6 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
}
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
onBumpFee(selChannel: Channel) {
this.store.dispatch(openAlert({
payload: {
@ -165,9 +164,16 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
});
}
loadChannelsTable(mychannels) {
// mychannels.sort((a, b) => ((a.active === b.active) ? 0 : ((b.active) ? 1 : -1)));
this.channels = new MatTableDataSource<Channel>([...mychannels]);
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.channels.filterPredicate = (channel: Channel, fltr: string) => {
const newChannel = ((channel.connected) ? 'connected' : 'disconnected') + (channel.channel_id ? channel.channel_id.toLowerCase() : '') +
(channel.short_channel_id ? channel.short_channel_id.toLowerCase() : '') + (channel.id ? channel.id.toLowerCase() : '') + (channel.alias ? channel.alias.toLowerCase() : '') +
@ -177,6 +183,33 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
(channel.our_channel_reserve_satoshis ? channel.our_channel_reserve_satoshis : '') + (channel.spendable_msatoshi ? channel.spendable_msatoshi : '');
return newChannel.includes(fltr);
};
// this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadChannelsTable(mychannels) {
this.channels = new MatTableDataSource<Channel>([...mychannels]);
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => {
switch (sortHeaderId) {
@ -189,6 +222,8 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
};
this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.channels.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.channels);
}

@ -8,11 +8,16 @@
<fa-icon [icon]="faUsers" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Connected Peers</span>
</div>
<mat-form-field fxFlex="30">
<div fxLayout="row" fxLayoutAlign="start start">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</div>
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -27,7 +32,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let peer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{peer?.alias}}</span>
</div>
</td>
@ -35,7 +40,7 @@
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let peer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{peer?.id}}</span>
</div>
</td>
@ -43,7 +48,7 @@
<ng-container matColumnDef="netaddr">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Network Address</th>
<td mat-cell *matCellDef="let peer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child" *ngFor="let addr of peer?.netaddr; last as isLast">{{addr}}<span *ngIf="!isLast">,<br></span></span>
</div>
</td>

@ -10,7 +10,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Peer, GetInfo, Balance } from '../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, ScreenSizeEnum, APICallStatusEnum, CLNActions, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, ScreenSizeEnum, APICallStatusEnum, CLNActions, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLN_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -22,7 +22,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../store/rtl.actions';
import { detachPeer } from '../../store/cln.actions';
import { clnPageSettings, nodeInfoAndBalance, peers } from '../../store/cln.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-peers',
@ -37,6 +38,8 @@ export class CLNPeersComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faUsers = faUsers;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'peers', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };
@ -57,7 +60,7 @@ export class CLNPeersComponent implements OnInit, AfterViewInit, OnDestroy {
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private actions: Actions, private commonService: CommonService) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private actions: Actions, private commonService: CommonService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -189,6 +192,38 @@ export class CLNPeersComponent implements OnInit, AfterViewInit, OnDestroy {
this.peers.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.peers.filterPredicate = (peer: Peer, fltr: string) => JSON.stringify(peer).toLowerCase().includes(fltr);
// this.peers.filterPredicate = (rowData: Peer, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadPeersTable(peersArr: Peer[]) {
this.peers = new MatTableDataSource<Peer>([...peersArr]);
this.peers.sortingDataAccessor = (data: any, sortHeaderId: string) => {
@ -206,8 +241,8 @@ export class CLNPeersComponent implements OnInit, AfterViewInit, OnDestroy {
};
this.peers.sort = this.sort;
this.peers.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.peers.filterPredicate = (peer: Peer, fltr: string) => JSON.stringify(peer).toLowerCase().includes(fltr);
this.peers.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}

@ -42,7 +42,7 @@
</ngx-charts-bar-vertical>
</div>
<div class="mt-1">
<rtl-cln-forwarding-history *ngIf="filteredEventsBySelectedPeriod && filteredEventsBySelectedPeriod.length > 0" [pageId]="'reports'" [tableId]="'routing'" [eventsData]="filteredEventsBySelectedPeriod" [filterValue]="eventFilterValue"></rtl-cln-forwarding-history>
<rtl-cln-forwarding-history *ngIf="filteredEventsBySelectedPeriod && filteredEventsBySelectedPeriod.length > 0" [pageId]="'reports'" [tableId]="'routing'" [eventsData]="filteredEventsBySelectedPeriod" [selFilter]="eventFilterValue"></rtl-cln-forwarding-history>
</div>
</div>
</div>

@ -35,7 +35,7 @@
</ngx-charts-bar-vertical-2d>
</div>
<div class="mt-1">
<rtl-transactions-report-table *ngIf="transactionsNonZeroReportData.length > 0" [displayedColumns]="displayedColumns" [tableSetting]="tableSetting" [dataList]="transactionsNonZeroReportData" [dataRange]="reportPeriod" [filterValue]="transactionFilterValue"></rtl-transactions-report-table>
<rtl-transactions-report-table *ngIf="transactionsNonZeroReportData.length > 0" [displayedColumns]="displayedColumns" [tableSetting]="tableSetting" [dataList]="transactionsNonZeroReportData" [dataRange]="reportPeriod" [selFilter]="transactionFilterValue"></rtl-transactions-report-table>
</div>
</div>
</div>

@ -7,9 +7,16 @@
</div>
<div fxFlex="100">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="errorMessage === ''" [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
@ -30,7 +37,7 @@
<ng-container matColumnDef="in_channel_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>In Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.in_channel_alias}}</span>
</span>
</td>
@ -42,7 +49,7 @@
<ng-container matColumnDef="out_channel_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Out Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.out_channel_alias}}</span>
</span>
</td>

@ -9,7 +9,7 @@ import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ForwardingEvent, ListForwards } from '../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, CLNForwardingEventsStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, CLNForwardingEventsStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLN_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -19,7 +19,8 @@ import { openAlert } from '../../../store/rtl.actions';
import { getForwardingHistory } from '../../store/cln.actions';
import { clnPageSettings, failedForwardingHistory } from '../../store/cln.selector';
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-failed-history',
@ -33,6 +34,8 @@ export class CLNFailedTransactionsComponent implements OnInit, AfterViewInit, On
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'routing';
public tableSetting: TableSetting = { tableId: 'failed', recordsPerPage: PAGE_SIZE, sortBy: 'received_time', sortOrder: SortOrderEnum.DESCENDING };
@ -51,7 +54,7 @@ export class CLNFailedTransactionsComponent implements OnInit, AfterViewInit, On
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private router: Router) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private router: Router, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -123,11 +126,16 @@ export class CLNFailedTransactionsComponent implements OnInit, AfterViewInit, On
}));
}
loadFailedEventsTable(forwardingEvents: ForwardingEvent[]) {
this.failedForwardingEvents = new MatTableDataSource<ForwardingEvent>([...forwardingEvents]);
this.failedForwardingEvents.sort = this.sort;
this.failedForwardingEvents.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.failedForwardingEvents.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
applyFilter() {
this.failedForwardingEvents.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.failedForwardingEvents.filterPredicate = (event: ForwardingEvent, fltr: string) => {
const newEvent =
(event.received_time ? this.datePipe.transform(new Date(event.received_time * 1000), 'dd/MMM/YYYY HH:mm')!.toLowerCase() : '') +
@ -138,7 +146,38 @@ export class CLNFailedTransactionsComponent implements OnInit, AfterViewInit, On
(event.in_msatoshi ? (event.in_msatoshi / 1000) : '') + (event.out_msatoshi ? (event.out_msatoshi / 1000) : '') + (event.fee ? event.fee : '');
return newEvent?.includes(fltr) || false;
};
// this.failedForwardingEvents.filterPredicate = (rowData: ForwardingEvent, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadFailedEventsTable(forwardingEvents: ForwardingEvent[]) {
this.failedForwardingEvents = new MatTableDataSource<ForwardingEvent>([...forwardingEvents]);
this.failedForwardingEvents.sort = this.sort;
this.failedForwardingEvents.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.failedForwardingEvents.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.failedForwardingEvents.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.failedForwardingEvents);
}
@ -149,10 +188,6 @@ export class CLNFailedTransactionsComponent implements OnInit, AfterViewInit, On
}
}
applyFilter() {
this.failedForwardingEvents.filter = this.selFilter.trim().toLowerCase();
}
ngOnDestroy() {
this.unSubs.forEach((completeSub) => {
completeSub.next(<any>null);

@ -2,9 +2,16 @@
<div class="p-2 error-border my-2" *ngIf="errorMessage !== ''">{{errorMessage}}</div>
<div *ngIf="errorMessage === ''" fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput [(ngModel)]="filterValue" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div *ngIf="errorMessage === ''" [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -24,7 +31,7 @@
<ng-container matColumnDef="in_channel_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>In Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.in_channel_alias}}</span>
</div>
</td>
@ -36,7 +43,7 @@
<ng-container matColumnDef="out_channel_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Out Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.out_channel_alias}}</span>
</div>
</td>
@ -44,7 +51,7 @@
<ng-container matColumnDef="payment_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.payment_hash}}</span>
</div>
</td>

@ -9,7 +9,7 @@ import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ForwardingEvent, ListForwards } from '../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, CLNForwardingEventsStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, CLNForwardingEventsStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLN_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -18,7 +18,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert } from '../../../store/rtl.actions';
import { clnPageSettings, forwardingHistory } from '../../store/cln.selector';
import { getForwardingHistory } from '../../store/cln.actions';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-forwarding-history',
@ -35,7 +36,9 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
@Input() pageId = 'routing';
@Input() tableId = 'forwarding_history';
@Input() eventsData = [];
@Input() filterValue = '';
@Input() selFilter = '';
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public tableSetting: TableSetting = { tableId: 'forwarding_history', recordsPerPage: PAGE_SIZE, sortBy: 'received_time', sortOrder: SortOrderEnum.DESCENDING };
public successfulEvents: ForwardingEvent[] = [];
@ -51,7 +54,7 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private router: Router) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private router: Router, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -117,7 +120,7 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
this.loadForwardingEventsTable(this.successfulEvents);
}
}
if (changes.filterValue && !changes.filterValue.firstChange) {
if (changes.selFilter && !changes.selFilter.firstChange) {
this.applyFilter();
}
}
@ -145,11 +148,18 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
}));
}
loadForwardingEventsTable(forwardingEvents: ForwardingEvent[]) {
this.forwardingHistoryEvents = new MatTableDataSource<ForwardingEvent>([...forwardingEvents]);
this.forwardingHistoryEvents.sort = this.sort;
this.forwardingHistoryEvents.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.forwardingHistoryEvents.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
applyFilter() {
if (this.forwardingHistoryEvents) {
this.forwardingHistoryEvents.filter = this.selFilter.trim().toLowerCase();
}
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.pageId][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.forwardingHistoryEvents.filterPredicate = (event: ForwardingEvent, fltr: string) => {
const newEvent = (event.received_time ? this.datePipe.transform(new Date(event.received_time * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() + ' ' : '') +
(event.resolved_time ? this.datePipe.transform(new Date(event.resolved_time * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() + ' ' : '') +
@ -158,7 +168,38 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
(event.in_msatoshi ? (event.in_msatoshi / 1000) + ' ' : '') + (event.out_msatoshi ? (event.out_msatoshi / 1000) + ' ' : '') + (event.fee ? event.fee + ' ' : '');
return newEvent.includes(fltr);
};
// this.forwardingHistoryEvents.filterPredicate = (rowData: ForwardingEvent, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadForwardingEventsTable(forwardingEvents: ForwardingEvent[]) {
this.forwardingHistoryEvents = new MatTableDataSource<ForwardingEvent>([...forwardingEvents]);
this.forwardingHistoryEvents.sort = this.sort;
this.forwardingHistoryEvents.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.forwardingHistoryEvents.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.forwardingHistoryEvents.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.forwardingHistoryEvents);
}
@ -169,12 +210,6 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
}
}
applyFilter() {
if (this.forwardingHistoryEvents) {
this.forwardingHistoryEvents.filter = this.filterValue.trim().toLowerCase();
}
}
ngOnDestroy() {
this.unSubs.forEach((completeSub) => {
completeSub.next(<any>null);

@ -7,9 +7,16 @@
</div>
<div fxFlex="100">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
</div>
<div *ngIf="errorMessage === ''" [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
@ -26,7 +33,7 @@
<ng-container matColumnDef="in_channel_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>In Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.in_channel_alias}}</span>
</span>
</td>
@ -38,7 +45,7 @@
<ng-container matColumnDef="out_channel_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Out Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.out_channel_alias}}</span>
</span>
</td>

@ -9,7 +9,7 @@ import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ListForwards, LocalFailedEvent } from '../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, CLNFailReason, CLNForwardingEventsStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, CLNFailReason, CLNForwardingEventsStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLN_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -19,7 +19,8 @@ import { openAlert } from '../../../store/rtl.actions';
import { getForwardingHistory } from '../../store/cln.actions';
import { clnPageSettings, localFailedForwardingHistory } from '../../store/cln.selector';
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-local-failed-history',
@ -34,6 +35,8 @@ export class CLNLocalFailedTransactionsComponent implements OnInit, AfterViewIni
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faExclamationTriangle = faExclamationTriangle;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'routing';
public tableSetting: TableSetting = { tableId: 'local_failed', recordsPerPage: PAGE_SIZE, sortBy: 'received_time', sortOrder: SortOrderEnum.DESCENDING };
@ -52,7 +55,7 @@ export class CLNLocalFailedTransactionsComponent implements OnInit, AfterViewIni
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private router: Router) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private router: Router, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -118,6 +121,48 @@ export class CLNLocalFailedTransactionsComponent implements OnInit, AfterViewIni
}));
}
applyFilter() {
this.failedLocalForwardingEvents.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.failedLocalForwardingEvents.filterPredicate = (event: LocalFailedEvent, fltr: string) => {
const newEvent = (event.received_time ? this.datePipe.transform(new Date(event.received_time * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') +
(event.in_channel_alias ? event.in_channel_alias.toLowerCase() : '') +
((event.failreason && this.CLNFailReason[event.failreason]) ? this.CLNFailReason[event.failreason].toLowerCase() : '') +
(event.in_msatoshi ? (event.in_msatoshi / 1000) : '');
return newEvent?.includes(fltr) || false;
};
// this.failedLocalForwardingEvents.filterPredicate = (rowData: LocalFailedEvent, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadLocalfailedLocalEventsTable(forwardingEvents: LocalFailedEvent[]) {
this.failedLocalForwardingEvents = new MatTableDataSource<LocalFailedEvent>([...forwardingEvents]);
this.failedLocalForwardingEvents.sort = this.sort;
@ -131,14 +176,8 @@ export class CLNLocalFailedTransactionsComponent implements OnInit, AfterViewIni
}
};
this.failedLocalForwardingEvents.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.failedLocalForwardingEvents.filterPredicate = (event: LocalFailedEvent, fltr: string) => {
const newEvent = (event.received_time ? this.datePipe.transform(new Date(event.received_time * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') +
(event.in_channel_alias ? event.in_channel_alias.toLowerCase() : '') +
((event.failreason && this.CLNFailReason[event.failreason]) ? this.CLNFailReason[event.failreason].toLowerCase() : '') +
(event.in_msatoshi ? (event.in_msatoshi / 1000) : '');
return newEvent?.includes(fltr) || false;
};
this.failedLocalForwardingEvents.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.failedLocalForwardingEvents);
}
@ -149,10 +188,6 @@ export class CLNLocalFailedTransactionsComponent implements OnInit, AfterViewIni
}
}
applyFilter() {
this.failedLocalForwardingEvents.filter = this.selFilter.trim().toLowerCase();
}
ngOnDestroy() {
this.unSubs.forEach((completeSub) => {
completeSub.next(<any>null);

@ -4,17 +4,24 @@
<div fxLayout="column" fxFlex="49" fxLayoutAlign="start stretch">
<div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="page-sub-title-container w-100" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS, 'mt-1': screenSize === screenSizeEnum.SM}">
<div fxFlex="70">Incoming</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyIncomingFilter()" [(ngModel)]="filterIn" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterByIn" (selectionChange)="selFilterIn=''; applyIncomingFilter()" name="filterByIn">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilterIn" (input)="applyIncomingFilter()" (keyup)="applyIncomingFilter()" name="filterin" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<table mat-table #tableIn [dataSource]="RoutingPeersIncoming" matSort class="overflow-auto incoming-table">
<table mat-table #tableIn [dataSource]="routingPeersIncoming" matSort class="overflow-auto incoming-table">
<ng-container matColumnDef="channel_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer.channel_id}}</span>
</div>
</td>
@ -22,7 +29,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer.alias}}</span>
</div>
</td>
@ -42,12 +49,12 @@
</ng-container>
<ng-container matColumnDef="no_incoming_event">
<td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.COMPLETED">No incoming routing peer available.</p>
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.INITIATED">Getting incoming routing peers...</p>
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.COMPLETED">No incoming routing peer available.</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.INITIATED">Getting incoming routing peers...</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="['no_incoming_event']" [ngClass]="{'display-none': RoutingPeersIncoming?.data && RoutingPeersIncoming?.data?.length>0}"></tr>
<tr mat-footer-row *matFooterRowDef="['no_incoming_event']" [ngClass]="{'display-none': routingPeersIncoming?.data && routingPeersIncoming?.data?.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
@ -57,17 +64,24 @@
<div fxLayout="column" fxFlex="49" fxLayoutAlign="end stretch">
<div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="page-sub-title-container w-100" [ngClass]="{'mt-2': screenSize !== screenSizeEnum.LG}">
<div fxFlex="70">Outgoing</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyOutgoingFilter()" [(ngModel)]="filterOut" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterByOut" (selectionChange)="selFilterOut=''; applyOutgoingFilter()" name="filterByOut">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilterOut" (input)="applyOutgoingFilter()" (keyup)="applyOutgoingFilter()" name="filterout" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start end" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<table mat-table #tableOut [dataSource]="RoutingPeersOutgoing" matSort class="overflow-auto outgoing-table">
<table mat-table #tableOut [dataSource]="routingPeersOutgoing" matSort class="overflow-auto outgoing-table">
<ng-container matColumnDef="channel_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer.channel_id}}</span>
</div>
</td>
@ -75,7 +89,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer.alias}}</span>
</div>
</td>
@ -95,12 +109,12 @@
</ng-container>
<ng-container matColumnDef="no_outgoing_event">
<td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.COMPLETED">No outgoing routing peer available.</p>
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.INITIATED">Getting outgoing routing peers...</p>
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.COMPLETED">No outgoing routing peer available.</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.INITIATED">Getting outgoing routing peers...</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus?.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="['no_outgoing_event']" [ngClass]="{'display-none': RoutingPeersOutgoing?.data && RoutingPeersOutgoing?.data?.length>0}"></tr>
<tr mat-footer-row *matFooterRowDef="['no_outgoing_event']" [ngClass]="{'display-none': routingPeersOutgoing?.data && routingPeersOutgoing?.data?.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

@ -6,7 +6,7 @@ import { Store } from '@ngrx/store';
import { MatSort } from '@angular/material/sort';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLNForwardingEventsStatusEnum } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLNForwardingEventsStatusEnum, CLN_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ForwardingEvent, ListForwards, RoutingPeer } from '../../../shared/models/clnModels';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
@ -14,8 +14,9 @@ import { CommonService } from '../../../shared/services/common.service';
import { RTLState } from '../../../store/rtl.state';
import { clnPageSettings, forwardingHistory } from '../../store/cln.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { getForwardingHistory } from '../../store/cln.actions';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-routing-peers',
@ -32,14 +33,17 @@ export class CLNRoutingPeersComponent implements OnInit, OnChanges, AfterViewIni
@ViewChild('paginatorIn', { static: false }) paginatorIn: MatPaginator | undefined;
@ViewChild('paginatorOut', { static: false }) paginatorOut: MatPaginator | undefined;
@Input() eventsData = [];
@Input() filterValue = '';
@Input() selFilter = '';
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterByIn = 'all';
public selFilterByOut = 'all';
public colWidth = '20rem';
public PAGE_ID = 'routing';
public tableSetting: TableSetting = { tableId: 'routing_peers', recordsPerPage: PAGE_SIZE, sortBy: 'total_fee', sortOrder: SortOrderEnum.DESCENDING };
public successfulEvents: ForwardingEvent[] = [];
public displayedColumns: any[] = [];
public RoutingPeersIncoming: any = [];
public RoutingPeersOutgoing: any = [];
public routingPeersIncoming: any = [];
public routingPeersOutgoing: any = [];
public pageSize = PAGE_SIZE;
public pageSizeOptions = PAGE_SIZE_OPTIONS;
public screenSize = '';
@ -51,7 +55,7 @@ export class CLNRoutingPeersComponent implements OnInit, OnChanges, AfterViewIni
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -112,30 +116,70 @@ export class CLNRoutingPeersComponent implements OnInit, OnChanges, AfterViewIni
}
}
applyIncomingFilter() {
this.routingPeersIncoming.filter = this.filterIn.toLowerCase();
}
applyOutgoingFilter() {
this.routingPeersOutgoing.filter = this.filterOut.toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.routingPeersIncoming.filterPredicate = (rpIn: RoutingPeer, fltr: string) => JSON.stringify(rpIn).toLowerCase().includes(fltr);
this.routingPeersOutgoing.filterPredicate = (rpOut: RoutingPeer, fltr: string) => JSON.stringify(rpOut).toLowerCase().includes(fltr);
// this.routingPeersIncoming.filterPredicate = (rowData: RoutingPeer, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadRoutingPeersTable(events: ForwardingEvent[]) {
if (events.length > 0) {
const results = this.groupRoutingPeers(events);
this.RoutingPeersIncoming = new MatTableDataSource<RoutingPeer[]>(results[0]);
this.RoutingPeersIncoming.sort = this.sortIn;
this.RoutingPeersIncoming.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.RoutingPeersIncoming.filterPredicate = (rpIn: RoutingPeer, fltr: string) => JSON.stringify(rpIn).toLowerCase().includes(fltr);
this.RoutingPeersIncoming.paginator = this.paginatorIn;
this.logger.info(this.RoutingPeersIncoming);
this.RoutingPeersOutgoing = new MatTableDataSource<RoutingPeer[]>(results[1]);
this.RoutingPeersOutgoing.sort = this.sortOut;
this.RoutingPeersOutgoing.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.RoutingPeersOutgoing.filterPredicate = (rpOut: RoutingPeer, fltr: string) => JSON.stringify(rpOut).toLowerCase().includes(fltr);
this.RoutingPeersOutgoing.paginator = this.paginatorOut;
this.logger.info(this.RoutingPeersOutgoing);
this.routingPeersIncoming = new MatTableDataSource<RoutingPeer[]>(results[0]);
this.routingPeersIncoming.sort = this.sortIn;
this.routingPeersIncoming.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.routingPeersIncoming.paginator = this.paginatorIn;
this.logger.info(this.routingPeersIncoming);
this.routingPeersOutgoing = new MatTableDataSource<RoutingPeer[]>(results[1]);
this.routingPeersOutgoing.sort = this.sortOut;
this.routingPeersOutgoing.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.routingPeersOutgoing.paginator = this.paginatorOut;
this.logger.info(this.routingPeersOutgoing);
} else {
// To reset table after other Forwarding history calls
this.RoutingPeersIncoming = new MatTableDataSource<RoutingPeer>([]);
this.RoutingPeersOutgoing = new MatTableDataSource<RoutingPeer>([]);
this.routingPeersIncoming = new MatTableDataSource<RoutingPeer>([]);
this.routingPeersOutgoing = new MatTableDataSource<RoutingPeer>([]);
}
this.setFilterPredicate();
this.applyIncomingFilter();
this.applyOutgoingFilter();
this.logger.info(this.RoutingPeersIncoming);
this.logger.info(this.RoutingPeersOutgoing);
this.logger.info(this.routingPeersIncoming);
this.logger.info(this.routingPeersOutgoing);
}
groupRoutingPeers(forwardingEvents: ForwardingEvent[]) {
@ -162,14 +206,6 @@ export class CLNRoutingPeersComponent implements OnInit, OnChanges, AfterViewIni
return [this.commonService.sortDescByKey(incomingResults, 'total_fee'), this.commonService.sortDescByKey(outgoingResults, 'total_fee')];
}
applyIncomingFilter() {
this.RoutingPeersIncoming.filter = this.filterIn.toLowerCase();
}
applyOutgoingFilter() {
this.RoutingPeersOutgoing.filter = this.filterOut.toLowerCase();
}
ngOnDestroy() {
this.unSubs.forEach((completeSub) => {
completeSub.next(<any>null);

@ -23,9 +23,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Invoices History</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -55,7 +62,7 @@
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.description}}</span>
</div>
</td>
@ -63,7 +70,7 @@
<ng-container matColumnDef="label">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Label</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.label}}</span>
</div>
</td>
@ -71,7 +78,7 @@
<ng-container matColumnDef="payment_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.payment_hash}}</span>
</div>
</td>
@ -79,7 +86,7 @@
<ng-container matColumnDef="bolt11">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Invoice</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.bolt11}}</span>
</div>
</td>

@ -9,7 +9,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, UI_MESSAGES, CLNActions, CLN_DEFAULT_PAGE_SETTINGS, SortOrderEnum } from '../../../../shared/services/consts-enums-functions';
import { CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, UI_MESSAGES, CLNActions, CLN_DEFAULT_PAGE_SETTINGS, SortOrderEnum, CLN_PAGE_DEFS } from '../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';
import { SelNodeChild } from '../../../../shared/models/RTLconfig';
import { GetInfo, Invoice, ListInvoices } from '../../../../shared/models/clnModels';
@ -24,7 +24,8 @@ import { RTLState } from '../../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../../store/rtl.actions';
import { deleteExpiredInvoice, invoiceLookup, saveNewInvoice } from '../../../store/cln.actions';
import { clnNodeInformation, clnNodeSettings, clnPageSettings, listInvoices } from '../../../store/cln.selector';
import { PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-lightning-invoices-table',
@ -40,6 +41,8 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'invoices', recordsPerPage: PAGE_SIZE, sortBy: 'expires_at', sortOrder: SortOrderEnum.DESCENDING };
@ -67,7 +70,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private rtlEffects: RTLEffects, private datePipe: DatePipe, private actions: Actions) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private rtlEffects: RTLEffects, private datePipe: DatePipe, private actions: Actions, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -203,6 +206,43 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
this.invoices.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
const newRowData = this.datePipe.transform(new Date((rowData.paid_at || 0) * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase()! +
(this.datePipe.transform(new Date((rowData.expires_at || 0) * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase()) +
((rowData.bolt12) ? 'bolt12' : (rowData.bolt11) ? 'bolt11' : 'keysend') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
onInvoiceValueChange() {
if (this.selNode && this.selNode.fiatConversion && this.invoiceValue! > 99) {
this.invoiceValueHint = '';
@ -231,14 +271,9 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
this.invoices.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.invoices.sort = this.sort;
this.invoices.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
const newRowData = this.datePipe.transform(new Date((rowData.paid_at || 0) * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase()! +
(this.datePipe.transform(new Date((rowData.expires_at || 0) * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase()) +
((rowData.bolt12) ? 'bolt12' : (rowData.bolt11) ? 'bolt11' : 'keysend') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.invoices.paginator = this.paginator;
this.applyFilter();
this.setFilterPredicate();
}
onDownloadCSV() {

@ -6,9 +6,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Offer Bookmarks</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -20,7 +27,7 @@
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Title</th>
<td mat-cell *matCellDef="let offersbookmark">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{offersbookmark.title}}</span>
</div>
</td>
@ -28,7 +35,7 @@
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
<td mat-cell *matCellDef="let offersbookmark">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{offersbookmark.description}}</span>
</div>
</td>
@ -40,7 +47,7 @@
<ng-container matColumnDef="bolt12">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Invoice</th>
<td mat-cell *matCellDef="let offersbookmark">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{offersbookmark.bolt12}}</span>
</div>
</td>

@ -7,7 +7,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, PaymentTypes, AlertTypeEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, UI_MESSAGES } from '../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, PaymentTypes, AlertTypeEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, UI_MESSAGES, CLN_PAGE_DEFS } from '../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';
import { OfferBookmark } from '../../../../shared/models/clnModels';
import { LoggerService } from '../../../../shared/services/logger.service';
@ -20,7 +20,8 @@ import { clnPageSettings, offerBookmarks } from '../../../store/cln.selector';
import { CLNOfferInformationComponent } from '../offer-information-modal/offer-information.component';
import { CLNLightningSendPaymentsComponent } from '../../send-payment-modal/send-payment.component';
import { deleteOfferBookmark, sendPayment } from '../../../store/cln.actions';
import { PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-offer-bookmarks-table',
@ -35,6 +36,8 @@ export class CLNOfferBookmarksTableComponent implements OnInit, AfterViewInit, O
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'offer_bookmarks', recordsPerPage: PAGE_SIZE, sortBy: 'lastUpdatedAt', sortOrder: SortOrderEnum.DESCENDING };
@ -51,7 +54,7 @@ export class CLNOfferBookmarksTableComponent implements OnInit, AfterViewInit, O
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private rtlEffects: RTLEffects) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private rtlEffects: RTLEffects, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -143,13 +146,45 @@ export class CLNOfferBookmarksTableComponent implements OnInit, AfterViewInit, O
this.offersBookmarks.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.offersBookmarks.filterPredicate = (Ofrbm: OfferBookmark, fltr: string) => JSON.stringify(Ofrbm).toLowerCase().includes(fltr);
// this.offersBookmarks.filterPredicate = (rowData: OfferBookmark, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadOffersTable(OffrBMs: OfferBookmark[]) {
this.offersBookmarks = (OffrBMs) ? new MatTableDataSource<OfferBookmark>([...OffrBMs]) : new MatTableDataSource([]);
this.offersBookmarks.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.offersBookmarks.sort = this.sort;
this.offersBookmarks.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.offersBookmarks.filterPredicate = (Ofrbm: OfferBookmark, fltr: string) => JSON.stringify(Ofrbm).toLowerCase().includes(fltr);
this.offersBookmarks.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}

@ -8,9 +8,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Offers History</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -25,7 +32,7 @@
<ng-container matColumnDef="offer_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Offer ID</th>
<td mat-cell *matCellDef="let offer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">
{{offer.offer_id}}
</span>
@ -45,7 +52,7 @@
<ng-container matColumnDef="bolt12">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Invoice</th>
<td mat-cell *matCellDef="let offer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">
{{offer.bolt12}}
</span>

@ -1,6 +1,6 @@
/* eslint-disable max-len */
import { Component, OnInit, OnDestroy, ViewChild, AfterViewInit } from '@angular/core';
import { DecimalPipe, DatePipe } from '@angular/common';
import { DecimalPipe } from '@angular/common';
import { Subject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
@ -11,7 +11,7 @@ import { MatTableDataSource } from '@angular/material/table';
import * as pdfMake from 'pdfmake/build/pdfmake';
import * as pdfFonts from 'pdfmake/build/vfs_fonts';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, AlertTypeEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, AlertTypeEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS, CLN_PAGE_DEFS } from '../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';
import { SelNodeChild } from '../../../../shared/models/RTLconfig';
import { GetInfo, Offer, OfferRequest } from '../../../../shared/models/clnModels';
@ -27,7 +27,8 @@ import { RTLState } from '../../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../../store/rtl.actions';
import { disableOffer } from '../../../store/cln.actions';
import { clnNodeInformation, clnNodeSettings, clnPageSettings, offers } from '../../../store/cln.selector';
import { PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-offers-table',
@ -42,6 +43,8 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'offers', recordsPerPage: PAGE_SIZE, sortBy: 'offer_id', sortOrder: SortOrderEnum.DESCENDING };
@ -69,7 +72,7 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private rtlEffects: RTLEffects, private dataService: DataService, private decimalPipe: DecimalPipe, private datePipe: DatePipe) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private rtlEffects: RTLEffects, private dataService: DataService, private decimalPipe: DecimalPipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -226,11 +229,12 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
this.offers.filter = this.selFilter.trim().toLowerCase();
}
loadOffersTable(offrs: Offer[]) {
this.offers = (offrs) ? new MatTableDataSource<Offer>([...offrs]) : new MatTableDataSource([]);
this.offers.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.offers.sort = this.sort;
this.offers.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.offers.filterPredicate = (rowData: Offer, fltr: string) => {
const newRowData = ((rowData.active) ? ' active' : ' inactive') + ((rowData.used) ? ' used' : ' unused') + ((rowData.single_use) ? ' single' : ' multiple') + JSON.stringify(rowData).toLowerCase();
if (fltr === 'active' || fltr === 'inactive' || fltr === 'used' || fltr === 'unused' || fltr === 'single' || fltr === 'multiple') {
@ -238,7 +242,38 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
}
return newRowData.includes(fltr);
};
// this.offers.filterPredicate = (rowData: Offer, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadOffersTable(offrs: Offer[]) {
this.offers = (offrs) ? new MatTableDataSource<Offer>([...offrs]) : new MatTableDataSource([]);
this.offers.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.offers.sort = this.sort;
this.offers.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.offers.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}

@ -19,9 +19,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Payments History</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start start">
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
@ -47,7 +54,7 @@
<ng-container matColumnDef="payment_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.payment_hash}}</span>
</span>
</td>
@ -55,7 +62,7 @@
<ng-container matColumnDef="bolt11">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Invoice</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.bolt11}}</span>
</span>
</td>
@ -63,7 +70,7 @@
<ng-container matColumnDef="label">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Label</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.label}}</span>
</span>
</td>
@ -71,7 +78,7 @@
<ng-container matColumnDef="destination">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Destination</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.destination}}</span>
</span>
</td>
@ -79,7 +86,7 @@
<ng-container matColumnDef="memo">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Memo</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.memo}}</span>
</span>
</td>
@ -148,7 +155,7 @@
</ng-container>
<ng-container matColumnDef="group_payment_hash">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.payment_hash}}</span>
</span>
<span *ngIf="payment.is_expanded">
@ -160,11 +167,11 @@
</ng-container>
<ng-container matColumnDef="group_bolt11">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.bolt11}}</span>
</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child"></span>
</span>
</span>
@ -172,11 +179,11 @@
</ng-container>
<ng-container matColumnDef="group_label">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.label}}</span>
</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child"></span>
</span>
</span>
@ -184,11 +191,11 @@
</ng-container>
<ng-container matColumnDef="group_destination">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.destination}}</span>
</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child"></span>
</span>
</span>
@ -196,11 +203,11 @@
</ng-container>
<ng-container matColumnDef="group_memo">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.memo}}</span>
</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="ellipsis-parent mpp-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="ellipsis-parent mpp-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child"></span>
</span>
</span>

@ -9,7 +9,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { GetInfo, Payment, PayRequest } from '../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, APICallStatusEnum, UI_MESSAGES, PaymentTypes, CLN_DEFAULT_PAGE_SETTINGS, SortOrderEnum } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, APICallStatusEnum, UI_MESSAGES, PaymentTypes, CLN_DEFAULT_PAGE_SETTINGS, SortOrderEnum, CLN_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { DataService } from '../../../shared/services/data.service';
import { LoggerService } from '../../../shared/services/logger.service';
@ -24,7 +24,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../store/rtl.actions';
import { sendPayment } from '../../store/cln.actions';
import { clnNodeInformation, clnNodeSettings, clnPageSettings, payments } from '../../store/cln.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-cln-lightning-payments',
@ -40,6 +41,8 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
@ViewChild('sendPaymentForm', { static: false }) form;
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = CLN_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'created_at', sortOrder: SortOrderEnum.DESCENDING };
@ -64,7 +67,16 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private clnEffects: CLNEffects, private decimalPipe: DecimalPipe, private titleCasePipe: TitleCasePipe, private datePipe: DatePipe, private dataService: DataService) {
constructor(
private logger: LoggerService,
private commonService: CommonService,
private store: Store<RTLState>,
private rtlEffects: RTLEffects,
private decimalPipe: DecimalPipe,
private titleCasePipe: TitleCasePipe,
private datePipe: DatePipe,
private dataService: DataService,
private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -301,16 +313,48 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
this.payments.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.payments.filterPredicate = (rowData: Payment, fltr: string) => {
const newRowData = ((rowData.created_at) ? this.datePipe.transform(new Date(rowData.created_at * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + ((rowData.bolt12) ? 'bolt12' : (rowData.bolt11) ? 'bolt11' : 'keysend') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.payments.filterPredicate = (rowData: Payment, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadPaymentsTable(payments: Payment[]) {
this.payments = (payments) ? new MatTableDataSource<Payment>([...payments]) : new MatTableDataSource([]);
this.payments.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.payments.sort = this.sort;
this.payments.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.payments.filterPredicate = (rowData: Payment, fltr: string) => {
const newRowData = ((rowData.created_at) ? this.datePipe.transform(new Date(rowData.created_at * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + ((rowData.bolt12) ? 'bolt12' : (rowData.bolt11) ? 'bolt11' : 'keysend') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.payments.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}

@ -4,9 +4,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Transaction History</span>
</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start start">
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start end" fxFlex="100" class="table-container">
@ -20,7 +27,7 @@
<ng-container matColumnDef="address">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Address</th>
<td mat-cell *matCellDef="let transaction">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{transaction?.address}}</span>
</div>
</td>
@ -28,7 +35,7 @@
<ng-container matColumnDef="blockHash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Blockhash</th>
<td mat-cell *matCellDef="let transaction">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{transaction?.blockHash}}</span>
</div>
</td>
@ -36,7 +43,7 @@
<ng-container matColumnDef="txid">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Transaction ID</th>
<td mat-cell *matCellDef="let transaction">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{transaction?.txid}}</span>
</div>
</td>

@ -10,7 +10,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { Transaction } from '../../../shared/models/eclModels';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -18,7 +18,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert } from '../../../store/rtl.actions';
import { fetchTransactions } from '../../store/ecl.actions';
import { eclPageSettings, transactions } from '../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-ecl-on-chain-transaction-history',
@ -33,6 +34,8 @@ export class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faHistory = faHistory;
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'on_chain';
public tableSetting: TableSetting = { tableId: 'transaction', recordsPerPage: PAGE_SIZE, sortBy: 'timestamp', sortOrder: SortOrderEnum.DESCENDING };
@ -48,7 +51,7 @@ export class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -90,6 +93,41 @@ export class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy
this.listTransactions.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.listTransactions.filterPredicate = (rowData: Transaction, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.listTransactions.filterPredicate = (rowData: Transaction, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
onTransactionClick(selTransaction: Transaction, event: any) {
const reorderedTransactions = [
[{ key: 'blockHash', value: selTransaction.blockHash, title: 'Block Hash', width: 100 }],
@ -116,11 +154,8 @@ export class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy
this.listTransactions.sort = this.sort;
this.listTransactions.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.listTransactions.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.listTransactions.filterPredicate = (rowData: Transaction, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.listTransactions.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.listTransactions);
}

@ -1,9 +1,16 @@
<div fxLayout="column" class="padding-gap">
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -26,7 +33,7 @@
<ng-container matColumnDef="channelId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.channelId}}</span>
</div>
</td>
@ -34,7 +41,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.alias}}</span>
</div>
</td>
@ -42,7 +49,7 @@
<ng-container matColumnDef="nodeId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Node ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.nodeId}}</span>
</div>
</td>

@ -8,7 +8,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
import { Channel, ChannelsStatus, GetInfo, LightningBalance, OnChainBalance, Peer } from '../../../../../shared/models/eclModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, AlertTypeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, AlertTypeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { CommonService } from '../../../../../shared/services/common.service';
@ -19,7 +19,8 @@ import { openAlert, openConfirmation } from '../../../../../store/rtl.actions';
import { RTLState } from '../../../../../store/rtl.state';
import { closeChannel } from '../../../../store/ecl.actions';
import { allChannelsInfo, eclNodeInformation, eclPageSettings, onchainBalance, peers } from '../../../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-ecl-channel-inactive-table',
@ -35,6 +36,8 @@ export class ECLChannelInactiveTableComponent implements OnInit, AfterViewInit,
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faEye = faEye;
public faEyeSlash = faEyeSlash;
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'inactive_channels', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };
@ -56,7 +59,7 @@ export class ECLChannelInactiveTableComponent implements OnInit, AfterViewInit,
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -141,10 +144,6 @@ export class ECLChannelInactiveTableComponent implements OnInit, AfterViewInit,
});
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLocaleLowerCase();
}
onChannelClick(selChannel: Channel, event: any) {
this.store.dispatch(openAlert({
payload: {
@ -157,13 +156,49 @@ export class ECLChannelInactiveTableComponent implements OnInit, AfterViewInit,
}));
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLocaleLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.channels.filterPredicate = (channel: Channel, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
// this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadChannelsTable() {
this.channels = new MatTableDataSource<Channel>([...this.inactiveChannels]);
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.channels.filterPredicate = (channel: Channel, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
this.channels.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.channels);
}

@ -1,9 +1,16 @@
<div fxLayout="column" class="padding-gap">
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -22,7 +29,7 @@
<ng-container matColumnDef="channelId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.channelId}}</span>
</div>
</td>
@ -30,7 +37,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.alias}}</span>
</div>
</td>
@ -38,7 +45,7 @@
<ng-container matColumnDef="nodeId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Node ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.nodeId}}</span>
</div>
</td>

@ -9,7 +9,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Channel, ChannelsStatus, GetInfo, LightningBalance, OnChainBalance, Peer } from '../../../../../shared/models/eclModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, AlertTypeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, AlertTypeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { CommonService } from '../../../../../shared/services/common.service';
@ -20,7 +20,8 @@ import { openAlert, openConfirmation } from '../../../../../store/rtl.actions';
import { RTLState } from '../../../../../store/rtl.state';
import { closeChannel, updateChannel } from '../../../../store/ecl.actions';
import { allChannelsInfo, eclNodeInformation, eclPageSettings, onchainBalance, peers } from '../../../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-ecl-channel-open-table',
@ -36,6 +37,8 @@ export class ECLChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faEye = faEye;
public faEyeSlash = faEyeSlash;
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'open_channels', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };
@ -57,7 +60,7 @@ export class ECLChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService, private router: Router) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService, private router: Router, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
this.selFilter = this.router.getCurrentNavigation()?.extras?.state?.filter ? this.router.getCurrentNavigation()?.extras?.state?.filter : '';
}
@ -211,10 +214,6 @@ export class ECLChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
});
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
onChannelClick(selChannel: Channel, event: any) {
this.store.dispatch(openAlert({
payload: {
@ -227,13 +226,49 @@ export class ECLChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
}));
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.channels.filterPredicate = (channel: Channel, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
// this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadChannelsTable() {
this.channels = new MatTableDataSource<Channel>([...this.activeChannels]);
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.channels.filterPredicate = (channel: Channel, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
this.channels.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.channels);
}

@ -1,9 +1,16 @@
<div fxLayout="column" class="padding-gap">
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -22,7 +29,7 @@
<ng-container matColumnDef="channelId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.channelId}}</span>
</div>
</td>
@ -34,7 +41,7 @@
<ng-container matColumnDef="nodeId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Node ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.nodeId}}</span>
</div>
</td>

@ -9,7 +9,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
import { Channel, ChannelsStatus, GetInfo, LightningBalance, OnChainBalance, Peer } from '../../../../../shared/models/eclModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';
import { ECLChannelInformationComponent } from '../../channel-information-modal/channel-information.component';
import { LoggerService } from '../../../../../shared/services/logger.service';
@ -18,7 +18,8 @@ import { CommonService } from '../../../../../shared/services/common.service';
import { openAlert } from '../../../../../store/rtl.actions';
import { RTLState } from '../../../../../store/rtl.state';
import { allChannelsInfo, eclNodeInformation, eclPageSettings, onchainBalance, peers } from '../../../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../../shared/pipes/app.pipe';
@Component({
@ -35,6 +36,8 @@ export class ECLChannelPendingTableComponent implements OnInit, AfterViewInit, O
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faEye = faEye;
public faEyeSlash = faEyeSlash;
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'pending_channels', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };
@ -56,7 +59,7 @@ export class ECLChannelPendingTableComponent implements OnInit, AfterViewInit, O
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -111,10 +114,6 @@ export class ECLChannelPendingTableComponent implements OnInit, AfterViewInit, O
}
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
onChannelClick(selChannel: Channel, event: any) {
this.store.dispatch(openAlert({
payload: {
@ -127,13 +126,49 @@ export class ECLChannelPendingTableComponent implements OnInit, AfterViewInit, O
}));
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.channels.filterPredicate = (channel: Channel, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
// this.channels.filterPredicate = (rowData: Channel, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadChannelsTable() {
this.channels = new MatTableDataSource<Channel>([...this.pendingChannels]);
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.channels.filterPredicate = (channel: Channel, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
this.channels.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.channels);
}

@ -8,11 +8,16 @@
<fa-icon [icon]="faUsers" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Peers</span>
</div>
<mat-form-field fxFlex="30">
<div fxLayout="row" fxLayoutAlign="start start">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</div>
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -27,7 +32,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let peer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{peer?.alias}}</span>
</div>
</td>
@ -35,7 +40,7 @@
<ng-container matColumnDef="nodeId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Node ID</th>
<td mat-cell *matCellDef="let peer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{peer?.nodeId}}</span>
</div>
</td>

@ -10,7 +10,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Peer, GetInfo, OnChainBalance } from '../../../shared/models/eclModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, ScreenSizeEnum, APICallStatusEnum, ECLActions, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, ScreenSizeEnum, APICallStatusEnum, ECLActions, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
@ -22,7 +22,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../store/rtl.actions';
import { disconnectPeer } from '../../store/ecl.actions';
import { eclNodeInformation, eclPageSettings, onchainBalance, peers } from '../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-ecl-peers',
@ -36,6 +37,8 @@ export class ECLPeersComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'peers', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };
@ -57,7 +60,7 @@ export class ECLPeersComponent implements OnInit, AfterViewInit, OnDestroy {
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private actions: Actions, private commonService: CommonService) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private actions: Actions, private commonService: CommonService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -204,13 +207,45 @@ export class ECLPeersComponent implements OnInit, AfterViewInit, OnDestroy {
this.peers.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.peers.filterPredicate = (peer: Peer, fltr: string) => JSON.stringify(peer).toLowerCase().includes(fltr);
// this.peers.filterPredicate = (rowData: Peer, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadPeersTable(peers: Peer[]) {
this.peers = (peers) ? new MatTableDataSource<Peer>([...peers]) : new MatTableDataSource([]);
this.peers.sort = this.sort;
this.peers.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.peers.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.peers.filterPredicate = (peer: Peer, fltr: string) => JSON.stringify(peer).toLowerCase().includes(fltr);
this.peers.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}

@ -37,7 +37,7 @@
</ngx-charts-bar-vertical>
</div>
<div class="mt-1">
<rtl-ecl-forwarding-history *ngIf="filteredEventsBySelectedPeriod.length > 0" [pageId]="'reports'" [tableId]="'routing'"[eventsData]="filteredEventsBySelectedPeriod" [filterValue]="eventFilterValue"></rtl-ecl-forwarding-history>
<rtl-ecl-forwarding-history *ngIf="filteredEventsBySelectedPeriod.length > 0" [pageId]="'reports'" [tableId]="'routing'"[eventsData]="filteredEventsBySelectedPeriod" [selFilter]="eventFilterValue"></rtl-ecl-forwarding-history>
</div>
</div>
</div>

@ -35,7 +35,7 @@
</ngx-charts-bar-vertical-2d>
</div>
<div class="mt-1">
<rtl-transactions-report-table *ngIf="transactionsNonZeroReportData.length > 0" [displayedColumns]="displayedColumns" [tableSetting]="tableSetting" [dataList]="transactionsNonZeroReportData" [dataRange]="reportPeriod" [filterValue]="transactionFilterValue"></rtl-transactions-report-table>
<rtl-transactions-report-table *ngIf="transactionsNonZeroReportData.length > 0" [displayedColumns]="displayedColumns" [tableSetting]="tableSetting" [dataList]="transactionsNonZeroReportData" [dataRange]="reportPeriod" [selFilter]="transactionFilterValue"></rtl-transactions-report-table>
</div>
</div>
</div>

@ -2,9 +2,16 @@
<div class="p-2 error-border my-2" *ngIf="errorMessage !== ''">{{errorMessage}}</div>
<div *ngIf="errorMessage === ''" fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput [(ngModel)]="filterValue" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div *ngIf="errorMessage === ''" [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -24,7 +31,7 @@
<ng-container matColumnDef="fromChannelId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>In Channel ID</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.fromChannelId}}</span>
</div>
</td>
@ -36,7 +43,7 @@
<ng-container matColumnDef="fromChannelAlias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>In Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.fromChannelAlias}}</span>
</div>
</td>
@ -44,7 +51,7 @@
<ng-container matColumnDef="toChannelId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Out Channel ID</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.toChannelId}}</span>
</div>
</td>
@ -56,7 +63,7 @@
<ng-container matColumnDef="toChannelAlias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Out Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.toChannelAlias}}</span>
</div>
</td>
@ -64,7 +71,7 @@
<ng-container matColumnDef="paymentHash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.paymentHash}}</span>
</div>
</td>

@ -8,7 +8,7 @@ import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { PaymentRelayed, Payments } from '../../../shared/models/eclModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -16,7 +16,8 @@ import { CommonService } from '../../../shared/services/common.service';
import { RTLState } from '../../../store/rtl.state';
import { openAlert } from '../../../store/rtl.actions';
import { eclPageSettings, payments } from '../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-ecl-forwarding-history',
@ -33,7 +34,9 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
@Input() pageId = 'routing';
@Input() tableId = 'forwarding_history';
@Input() eventsData: PaymentRelayed[] = [];
@Input() filterValue = '';
@Input() selFilter = '';
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public tableSetting: TableSetting = { tableId: 'forwarding_history', recordsPerPage: PAGE_SIZE, sortBy: 'timestamp', sortOrder: SortOrderEnum.DESCENDING };
public displayedColumns: any[] = [];
@ -47,7 +50,7 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -103,7 +106,7 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
this.loadForwardingEventsTable(this.eventsData);
}
}
if (changes.filterValue && !changes.filterValue.firstChange) {
if (changes.selFilter && !changes.selFilter.firstChange) {
this.applyFilter();
}
}
@ -136,6 +139,47 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
}));
}
applyFilter() {
if (this.forwardingHistoryEvents) {
this.forwardingHistoryEvents.filter = this.selFilter.trim().toLowerCase();
}
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.pageId][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.forwardingHistoryEvents.filterPredicate = (rowData: PaymentRelayed, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.forwardingHistoryEvents.filterPredicate = (rowData: PaymentRelayed, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadForwardingEventsTable(forwardingEvents: PaymentRelayed[]) {
this.forwardingHistoryEvents = new MatTableDataSource<PaymentRelayed>([...forwardingEvents]);
this.forwardingHistoryEvents.sort = this.sort;
@ -149,11 +193,8 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
}
};
this.forwardingHistoryEvents.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.forwardingHistoryEvents.filterPredicate = (rowData: PaymentRelayed, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.forwardingHistoryEvents.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.forwardingHistoryEvents);
}
@ -164,12 +205,6 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
}
}
applyFilter() {
if (this.forwardingHistoryEvents) {
this.forwardingHistoryEvents.filter = this.filterValue.trim().toLowerCase();
}
}
ngOnDestroy() {
this.unSubs.forEach((completeSub) => {
completeSub.next(<any>null);

@ -4,17 +4,24 @@
<div fxLayout="column" fxFlex="49" fxLayoutAlign="start stretch" class="mb-4">
<div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="page-sub-title-container w-100" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS, 'mt-1': screenSize === screenSizeEnum.SM}">
<div fxFlex="70">Incoming</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyIncomingFilter()" [(ngModel)]="filterIn" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterByIn" (selectionChange)="selFilterIn=''; applyIncomingFilter()" name="filterByIn">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilterIn" (input)="applyIncomingFilter()" (keyup)="applyIncomingFilter()" name="filterin" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start start" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<table mat-table #tableIn [dataSource]="RoutingPeersIncoming" matSort class="overflow-auto incoming-table">
<table mat-table #tableIn [dataSource]="routingPeersIncoming" matSort class="overflow-auto incoming-table">
<ng-container matColumnDef="channelId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer?.channelId}}</span>
</div>
</td>
@ -22,7 +29,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer?.alias}}</span>
</div>
</td>
@ -42,12 +49,12 @@
</ng-container>
<ng-container matColumnDef="no_incoming_event">
<td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">No incoming routing peer available.</p>
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting incoming routing peers...</p>
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">No incoming routing peer available.</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting incoming routing peers...</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="['no_incoming_event']" [ngClass]="{'display-none': RoutingPeersIncoming?.data && RoutingPeersIncoming?.data?.length>0}"></tr>
<tr mat-footer-row *matFooterRowDef="['no_incoming_event']" [ngClass]="{'display-none': routingPeersIncoming?.data && routingPeersIncoming?.data?.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
@ -57,17 +64,24 @@
<div fxLayout="column" fxFlex="49" fxLayoutAlign="end stretch" class="mb-4">
<div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="page-sub-title-container w-100" [ngClass]="{'mt-2': screenSize !== screenSizeEnum.LG}">
<div fxFlex="70">Outgoing</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyOutgoingFilter()" [(ngModel)]="filterOut" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterByOut" (selectionChange)="selFilterOut=''; applyOutgoingFilter()" name="filterByOut">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilterOut" (input)="applyOutgoingFilter()" (keyup)="applyOutgoingFilter()" name="filterout" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start end" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<table mat-table #tableOut [dataSource]="RoutingPeersOutgoing" matSort class="overflow-auto outgoing-table">
<table mat-table #tableOut [dataSource]="routingPeersOutgoing" matSort class="overflow-auto outgoing-table">
<ng-container matColumnDef="channelId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer?.channelId}}</span>
</div>
</td>
@ -75,7 +89,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer?.alias}}</span>
</div>
</td>
@ -95,12 +109,12 @@
</ng-container>
<ng-container matColumnDef="no_outgoing_event">
<td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">No outgoing routing peer available.</p>
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting outgoing routing peers...</p>
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">No outgoing routing peer available.</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting outgoing routing peers...</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="['no_outgoing_event']" [ngClass]="{'display-none': RoutingPeersOutgoing?.data && RoutingPeersOutgoing?.data?.length>0}"></tr>
<tr mat-footer-row *matFooterRowDef="['no_outgoing_event']" [ngClass]="{'display-none': routingPeersOutgoing?.data && routingPeersOutgoing?.data?.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

@ -7,7 +7,7 @@ import { MatSort } from '@angular/material/sort';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatTableDataSource } from '@angular/material/table';
import { PaymentRelayed, Payments, RoutingPeers } from '../../../shared/models/eclModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -15,6 +15,7 @@ import { CommonService } from '../../../shared/services/common.service';
import { RTLState } from '../../../store/rtl.state';
import { eclPageSettings, payments } from '../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-ecl-routing-peers',
@ -30,13 +31,16 @@ export class ECLRoutingPeersComponent implements OnInit, AfterViewInit, OnDestro
@ViewChild('tableOut', { read: MatSort, static: false }) sortOut: MatSort;
@ViewChild('paginatorIn', { static: false }) paginatorIn: MatPaginator | undefined;
@ViewChild('paginatorOut', { static: false }) paginatorOut: MatPaginator | undefined;
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterByIn = 'all';
public selFilterByOut = 'all';
public colWidth = '20rem';
public PAGE_ID = 'routing';
public tableSetting: TableSetting = { tableId: 'routing_peers', recordsPerPage: PAGE_SIZE, sortBy: 'totalFee', sortOrder: SortOrderEnum.DESCENDING };
public routingPeersData: PaymentRelayed[] = [];
public displayedColumns: any[] = [];
public RoutingPeersIncoming: any = new MatTableDataSource([]);
public RoutingPeersOutgoing: any = new MatTableDataSource([]);
public routingPeersIncoming: any = new MatTableDataSource([]);
public routingPeersOutgoing: any = new MatTableDataSource([]);
public pageSize = PAGE_SIZE;
public pageSizeOptions = PAGE_SIZE_OPTIONS;
public screenSize = '';
@ -48,7 +52,7 @@ export class ECLRoutingPeersComponent implements OnInit, AfterViewInit, OnDestro
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -94,22 +98,22 @@ export class ECLRoutingPeersComponent implements OnInit, AfterViewInit, OnDestro
loadRoutingPeersTable(forwardingEvents: PaymentRelayed[]) {
if (forwardingEvents.length > 0) {
const results = this.groupRoutingPeers(forwardingEvents);
this.RoutingPeersIncoming = new MatTableDataSource<RoutingPeers>(results[0]);
this.RoutingPeersIncoming.sort = this.sortIn;
this.RoutingPeersIncoming.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.RoutingPeersIncoming.filterPredicate = (rpIn: RoutingPeers, fltr: string) => JSON.stringify(rpIn).toLowerCase().includes(fltr);
this.RoutingPeersIncoming.paginator = this.paginatorIn;
this.logger.info(this.RoutingPeersIncoming);
this.RoutingPeersOutgoing = new MatTableDataSource<RoutingPeers>(results[1]);
this.RoutingPeersOutgoing.sort = this.sortOut;
this.RoutingPeersOutgoing.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.RoutingPeersOutgoing.filterPredicate = (rpOut: RoutingPeers, fltr: string) => JSON.stringify(rpOut).toLowerCase().includes(fltr);
this.RoutingPeersOutgoing.paginator = this.paginatorOut;
this.logger.info(this.RoutingPeersOutgoing);
this.routingPeersIncoming = new MatTableDataSource<RoutingPeers>(results[0]);
this.routingPeersIncoming.sort = this.sortIn;
this.routingPeersIncoming.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.routingPeersIncoming.filterPredicate = (rpIn: RoutingPeers, fltr: string) => JSON.stringify(rpIn).toLowerCase().includes(fltr);
this.routingPeersIncoming.paginator = this.paginatorIn;
this.logger.info(this.routingPeersIncoming);
this.routingPeersOutgoing = new MatTableDataSource<RoutingPeers>(results[1]);
this.routingPeersOutgoing.sort = this.sortOut;
this.routingPeersOutgoing.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.routingPeersOutgoing.filterPredicate = (rpOut: RoutingPeers, fltr: string) => JSON.stringify(rpOut).toLowerCase().includes(fltr);
this.routingPeersOutgoing.paginator = this.paginatorOut;
this.logger.info(this.routingPeersOutgoing);
} else {
// To reset table after other Forwarding history calls
this.RoutingPeersIncoming = new MatTableDataSource<RoutingPeers>([]);
this.RoutingPeersOutgoing = new MatTableDataSource<RoutingPeers>([]);
this.routingPeersIncoming = new MatTableDataSource<RoutingPeers>([]);
this.routingPeersOutgoing = new MatTableDataSource<RoutingPeers>([]);
}
this.applyIncomingFilter();
this.applyOutgoingFilter();
@ -140,11 +144,11 @@ export class ECLRoutingPeersComponent implements OnInit, AfterViewInit, OnDestro
}
applyIncomingFilter() {
this.RoutingPeersIncoming.filter = this.filterIn.toLowerCase();
this.routingPeersIncoming.filter = this.filterIn.toLowerCase();
}
applyOutgoingFilter() {
this.RoutingPeersOutgoing.filter = this.filterOut.toLowerCase();
this.routingPeersOutgoing.filter = this.filterOut.toLowerCase();
}
ngOnDestroy() {

@ -23,9 +23,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Invoices History</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -53,7 +60,7 @@
<ng-container matColumnDef="nodeId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Node ID</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.nodeId}}</span>
</div>
</td>
@ -61,7 +68,7 @@
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.description}}</span>
</div>
</td>
@ -69,7 +76,7 @@
<ng-container matColumnDef="paymentHash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.paymentHash}}</span>
</div>
</td>

@ -9,7 +9,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, ECLActions, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, ECLActions, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { SelNodeChild } from '../../../shared/models/RTLconfig';
import { GetInfo, Invoice } from '../../../shared/models/eclModels';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
@ -23,7 +23,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert } from '../../../store/rtl.actions';
import { createInvoice, invoiceLookup } from '../../store/ecl.actions';
import { eclNodeInformation, eclNodeSettings, eclPageSettings, invoices } from '../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-ecl-lightning-invoices',
@ -39,6 +40,8 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory;
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'invoices', recordsPerPage: PAGE_SIZE, sortBy: 'expiresAt', sortOrder: SortOrderEnum.DESCENDING };
@ -64,7 +67,7 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private datePipe: DatePipe, private actions: Actions) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private datePipe: DatePipe, private actions: Actions, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -174,16 +177,52 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
this.invoiceJSONArr = this.invoiceJSONArr?.map((invoice) => ((invoice.paymentHash === newInvoice.paymentHash) ? newInvoice : invoice));
}
applyFilter() {
this.invoices.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadInvoicesTable(invs: Invoice[]) {
this.invoices = invs ? new MatTableDataSource<Invoice>([...invs]) : new MatTableDataSource<Invoice>([]);
this.invoices.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.invoices.sort = this.sort;
this.invoices.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.invoices.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}
@ -194,10 +233,6 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
this.invoiceValueHint = '';
}
applyFilter() {
this.invoices.filter = this.selFilter.trim().toLowerCase();
}
onInvoiceValueChange() {
if (this.selNode && this.selNode.fiatConversion && this.invoiceValue && this.invoiceValue > 99) {
this.invoiceValueHint = '';

@ -19,9 +19,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Payments History</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start start">
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="colWidth" class="table-container">
@ -34,7 +41,7 @@
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let payment">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.id}}</span>
</div>
</td>
@ -42,7 +49,7 @@
<ng-container matColumnDef="recipientNodeId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Destination Node ID</th>
<td mat-cell *matCellDef="let payment">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.recipientNodeId}}</span>
</div>
</td>
@ -50,7 +57,7 @@
<ng-container matColumnDef="recipientNodeAlias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Destination</th>
<td mat-cell *matCellDef="let payment">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.recipientNodeAlias}}</span>
</div>
</td>
@ -58,7 +65,7 @@
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
<td mat-cell *matCellDef="let payment">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.description}}</span>
</div>
</td>
@ -66,7 +73,7 @@
<ng-container matColumnDef="paymentHash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let payment">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.paymentHash}}</span>
</div>
</td>
@ -74,7 +81,7 @@
<ng-container matColumnDef="paymentPreimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Preimage</th>
<td mat-cell *matCellDef="let payment">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.paymentPreimage}}</span>
</div>
</td>
@ -119,12 +126,12 @@
</ng-container>
<ng-container matColumnDef="group_id">
<td mat-cell *matCellDef="let payment">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.id}}</span>
</div>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let part of payment?.parts" fxLayoutAlign="start center" class="part-row-span">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{part.id}}</span>
</span>
</span>
@ -133,12 +140,12 @@
</ng-container>
<ng-container matColumnDef="group_recipientNodeId">
<td mat-cell *matCellDef="let payment">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.recipientNodeId}}</span>
</div>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let part of payment?.parts" fxLayoutAlign="start center" class="part-row-span">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{part.toChannelId}}</span>
</span>
</span>
@ -147,12 +154,12 @@
</ng-container>
<ng-container matColumnDef="group_recipientNodeAlias">
<td mat-cell *matCellDef="let payment">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.recipientNodeAlias}}</span>
</div>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let part of payment?.parts" fxLayoutAlign="start center" class="part-row-span">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{part.toChannelAlias}}</span>
</span>
</span>
@ -171,12 +178,12 @@
</ng-container>
<ng-container matColumnDef="group_description">
<td mat-cell *matCellDef="let payment">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.description}}</span>
</div>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let part of payment?.parts" fxLayoutAlign="start center" class="part-row-span">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">Fee Paid: {{part.feesPaid | number:'1.0-0'}} (Sats)</span>
</span>
</span>
@ -185,12 +192,12 @@
</ng-container>
<ng-container matColumnDef="group_paymentHash">
<td mat-cell *matCellDef="let payment">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.paymentHash}}</span>
</div>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let part of payment?.parts" fxLayoutAlign="start center" class="part-row-span">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">Fee Paid: {{part.feesPaid | number:'1.0-0'}} (Sats)</span>
</span>
</span>
@ -199,12 +206,12 @@
</ng-container>
<ng-container matColumnDef="group_paymentPreimage">
<td mat-cell *matCellDef="let payment">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.paymentPreimage}}</span>
</div>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let part of payment?.parts" fxLayoutAlign="start center" class="part-row-span">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayoutAlign="start center" class="ellipsis-parent part-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">Fee Paid: {{part.feesPaid | number:'1.0-0'}} (Sats)</span>
</span>
</span>

@ -9,7 +9,7 @@ import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { GetInfo, PayRequest, PaymentSent, PaymentSentPart, Payments } from '../../../shared/models/eclModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -24,7 +24,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../store/rtl.actions';
import { sendPayment } from '../../store/ecl.actions';
import { eclNodeInformation, eclNodeSettings, eclPageSettings, payments } from '../../store/ecl.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-ecl-lightning-payments',
@ -40,6 +41,8 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
@ViewChild('sendPaymentForm', { static: false }) form;
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = ECL_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'firstPartTimestamp', sortOrder: SortOrderEnum.DESCENDING };
@ -64,7 +67,7 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private decimalPipe: DecimalPipe, private dataService: DataService, private datePipe: DatePipe) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private decimalPipe: DecimalPipe, private dataService: DataService, private datePipe: DatePipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -118,6 +121,45 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
}
}
applyFilter() {
this.payments.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.payments.filterPredicate = (rowData: PaymentSent, fltr: string) => {
const newRowData = ((rowData.firstPartTimestamp) ? this.datePipe.transform(new Date(rowData.firstPartTimestamp), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.payments.filterPredicate = (rowData: PaymentSent, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadPaymentsTable(payms: PaymentSent[]) {
this.payments = payms ? new MatTableDataSource<PaymentSent>([...payms]) : new MatTableDataSource<PaymentSent>([]);
this.payments.sort = this.sort;
@ -144,11 +186,8 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
}
};
this.payments.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.payments.filterPredicate = (rowData: PaymentSent, fltr: string) => {
const newRowData = ((rowData.firstPartTimestamp) ? this.datePipe.transform(new Date(rowData.firstPartTimestamp), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.payments.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}
@ -363,10 +402,6 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
}));
}
applyFilter() {
this.payments.filter = this.selFilter.trim().toLowerCase();
}
onDownloadCSV() {
if (this.payments.data && this.payments.data.length > 0) {
const paymentsDataCopy: PaymentSent[] = JSON.parse(JSON.stringify(this.payments.data));

@ -19,9 +19,12 @@
<fa-icon [icon]="faArchive" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Backups</span>
</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<div fxFlex="49"></div>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>

@ -14,9 +14,12 @@
</div>
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container mt-2">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<div fxFlex="49"></div>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>

@ -33,7 +33,7 @@
<ng-container matColumnDef="pubkey_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer</th>
<td mat-cell *matCellDef="let hop">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{hop?.pubkey_alias}}</span>
</div>
</td>
@ -41,7 +41,7 @@
<ng-container matColumnDef="pub_key">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Pubkey</th>
<td mat-cell *matCellDef="let hop">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{hop?.pub_key}}</span>
</div>
</td>
@ -49,7 +49,7 @@
<ng-container matColumnDef="chan_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let hop">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{hop?.chan_id}}</span>
</div>
</td>

@ -1,8 +1,15 @@
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch" class="padding-gap-x-large">
<div fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign.gt-xs="end stretch" fxLayoutAlign="start stretch" class="page-sub-title-container">
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start start">
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start end" fxFlex="100" class="table-container">
@ -15,7 +22,7 @@
<ng-container matColumnDef="label">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Label</th>
<td mat-cell *matCellDef="let transaction">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{transaction?.label}}</span>
</div>
</td>
@ -23,7 +30,7 @@
<ng-container matColumnDef="block_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Block Hash</th>
<td mat-cell *matCellDef="let transaction">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{transaction?.block_hash}}</span>
</div>
</td>
@ -31,7 +38,7 @@
<ng-container matColumnDef="tx_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Transaction Hash</th>
<td mat-cell *matCellDef="let transaction">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{transaction?.tx_hash}}</span>
</div>
</td>

@ -9,7 +9,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Transaction } from '../../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../../shared/services/logger.service';
import { CommonService } from '../../../../shared/services/common.service';
@ -17,7 +17,8 @@ import { CommonService } from '../../../../shared/services/common.service';
import { RTLState } from '../../../../store/rtl.state';
import { openAlert } from '../../../../store/rtl.actions';
import { lndPageSettings, transactions } from '../../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-on-chain-transaction-history',
@ -31,6 +32,8 @@ export class OnChainTransactionHistoryComponent implements OnInit, OnChanges, On
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'on_chain';
public tableSetting: TableSetting = { tableId: 'transactions', recordsPerPage: PAGE_SIZE, sortBy: 'time_stamp', sortOrder: SortOrderEnum.DESCENDING };
@ -48,7 +51,7 @@ export class OnChainTransactionHistoryComponent implements OnInit, OnChanges, On
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -92,10 +95,6 @@ export class OnChainTransactionHistoryComponent implements OnInit, OnChanges, On
}
}
applyFilter() {
this.listTransactions.filter = this.selFilter.trim().toLowerCase();
}
onTransactionClick(selTransaction: Transaction) {
const reorderedTransactions = [
[{ key: 'block_hash', value: selTransaction.block_hash, title: 'Block Hash', width: 100 }],
@ -120,16 +119,52 @@ export class OnChainTransactionHistoryComponent implements OnInit, OnChanges, On
}));
}
applyFilter() {
this.listTransactions.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.listTransactions.filterPredicate = (rowData: Transaction, fltr: string) => {
const newRowData = ((rowData.time_stamp) ? this.datePipe.transform(new Date(rowData.time_stamp * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.listTransactions.filterPredicate = (rowData: Transaction, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case 'time_stamp':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadTransactionsTable(transactions) {
this.listTransactions = new MatTableDataSource<Transaction>([...transactions]);
this.listTransactions.sort = this.sort;
this.listTransactions.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.listTransactions.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.listTransactions.filterPredicate = (rowData: Transaction, fltr: string) => {
const newRowData = ((rowData.time_stamp) ? this.datePipe.transform(new Date(rowData.time_stamp * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.listTransactions.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.listTransactions);
}

@ -7,7 +7,7 @@
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
@ -26,7 +26,7 @@
<ng-container matColumnDef="tx_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Transaction ID</th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{utxo.outpoint.txid_str}}</span>
</span>
</td>
@ -40,7 +40,7 @@
<ng-container matColumnDef="label">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Label</th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{utxo.label}}</span>
</span>
</td>
@ -56,7 +56,7 @@
<ng-container matColumnDef="address">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Address</th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{utxo?.address}}</span>
</span>
</td>

@ -111,50 +111,50 @@ export class OnChainUTXOsComponent implements OnInit, OnChanges, OnDestroy {
}
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'All';
}
applyFilter() {
this.listUTXOs.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.listUTXOs.filterPredicate = (utxo: UTXO, fltr: string) => {
let newUTXO = '';
this.listUTXOs.filterPredicate = (rowData: UTXO, fltr: string) => {
let rowToFilter = '';
switch (this.selFilterBy) {
case 'all':
for (let i = 0; i < this.displayedColumns.length - 1; i++) {
newUTXO = newUTXO + (
rowToFilter = rowToFilter + (
(this.displayedColumns[i] === 'tx_id') ?
(utxo.outpoint && utxo.outpoint.txid_str ? utxo.outpoint.txid_str.toLowerCase() : '') :
(rowData.outpoint && rowData.outpoint.txid_str ? rowData.outpoint.txid_str.toLowerCase() : '') :
(this.displayedColumns[i] === 'output') ?
(utxo.outpoint && utxo.outpoint.output_index ? utxo.outpoint.output_index.toString() : '0') :
(rowData.outpoint && rowData.outpoint.output_index ? rowData.outpoint.output_index.toString() : '0') :
(this.displayedColumns[i] === 'address_type') ?
(utxo.address_type && this.addressType[utxo.address_type] && this.addressType[utxo.address_type].name ? this.addressType[utxo.address_type].name.toLowerCase() : '') :
(utxo[this.displayedColumns[i]] ? utxo[this.displayedColumns[i]].toLowerCase() : '')
(rowData.address_type && this.addressType[rowData.address_type] && this.addressType[rowData.address_type].name ? this.addressType[rowData.address_type].name.toLowerCase() : '') :
(rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
) + ', ';
}
break;
case 'tx_id':
newUTXO = (utxo.outpoint && utxo.outpoint.txid_str ? utxo.outpoint.txid_str.toLowerCase() : '');
rowToFilter = (rowData.outpoint && rowData.outpoint.txid_str ? rowData.outpoint.txid_str.toLowerCase() : '');
break;
case 'output':
newUTXO = (utxo.outpoint && utxo.outpoint.output_index ? utxo.outpoint.output_index.toString() : '0');
rowToFilter = (rowData.outpoint && rowData.outpoint.output_index ? rowData.outpoint.output_index.toString() : '0');
break;
case 'address_type':
newUTXO = (utxo.address_type && this.addressType[utxo.address_type] && this.addressType[utxo.address_type].name ? this.addressType[utxo.address_type].name.toLowerCase() : '');
rowToFilter = (rowData.address_type && this.addressType[rowData.address_type] && this.addressType[rowData.address_type].name ? this.addressType[rowData.address_type].name.toLowerCase() : '');
break;
default:
newUTXO = (utxo[this.selFilterBy] ? utxo[this.selFilterBy].toLowerCase() : '');
rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
break;
}
return newUTXO.includes(fltr);
return rowToFilter.includes(fltr);
};
}

@ -1,9 +1,16 @@
<div fxLayout="column" class="padding-gap">
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>

@ -8,7 +8,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { ChannelInformationComponent } from '../../channel-information-modal/channel-information.component';
import { Channel, ChannelHTLC, ChannelsSummary, LightningBalance } from '../../../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { CommonService } from '../../../../../shared/services/common.service';
@ -16,7 +16,8 @@ import { CommonService } from '../../../../../shared/services/common.service';
import { openAlert } from '../../../../../store/rtl.actions';
import { RTLState } from '../../../../../store/rtl.state';
import { channels, lndPageSettings } from '../../../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-channel-active-htlcs-table',
@ -30,6 +31,8 @@ export class ChannelActiveHTLCsTableComponent implements OnInit, AfterViewInit,
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'active_HTLCs', recordsPerPage: PAGE_SIZE, sortBy: 'expiration_height', sortOrder: SortOrderEnum.DESCENDING };
@ -47,7 +50,7 @@ export class ChannelActiveHTLCsTableComponent implements OnInit, AfterViewInit,
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -122,6 +125,42 @@ export class ChannelActiveHTLCsTableComponent implements OnInit, AfterViewInit,
this.channels.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.channels.filterPredicate = (channel: Channel, fltr: string) => {
const newChannel = (channel.remote_alias ? channel.remote_alias.toLowerCase() : '') +
channel.pending_htlcs?.map((htlc) => JSON.stringify(htlc) + (htlc.incoming ? 'yes' : 'no'));
return newChannel.includes(fltr);
};
// this.channels.filterPredicate = (rowData: Channel, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadHTLCsTable(channels: Channel[]) {
this.channels = (channels) ? new MatTableDataSource<Channel>([...channels]) : new MatTableDataSource([]);
this.channels.sort = this.sort;
@ -149,11 +188,7 @@ export class ChannelActiveHTLCsTableComponent implements OnInit, AfterViewInit,
};
this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.channels.paginator = this.paginator;
this.channels.filterPredicate = (channel: Channel, fltr: string) => {
const newChannel = (channel.remote_alias ? channel.remote_alias.toLowerCase() : '') +
channel.pending_htlcs?.map((htlc) => JSON.stringify(htlc) + (htlc.incoming ? 'yes' : 'no'));
return newChannel.includes(fltr);
};
this.setFilterPredicate();
this.applyFilter();
}

@ -1,9 +1,16 @@
<div fxLayout="column">
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -20,7 +27,7 @@
<ng-container matColumnDef="remote_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.remote_alias}}</span>
</div>
</td>
@ -28,7 +35,7 @@
<ng-container matColumnDef="remote_pubkey">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Pubkey</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.remote_pubkey}}</span>
</div>
</td>
@ -36,7 +43,7 @@
<ng-container matColumnDef="channel_point">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel Point</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.channel_point}}</span>
</div>
</td>
@ -44,7 +51,7 @@
<ng-container matColumnDef="chan_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.chan_id}}</span>
</div>
</td>
@ -52,7 +59,7 @@
<ng-container matColumnDef="closing_tx_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Closing Tx Hash</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.closing_tx_hash}}</span>
</div>
</td>
@ -60,7 +67,7 @@
<ng-container matColumnDef="chain_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Chain Hash</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel?.chain_hash}}</span>
</div>
</td>

@ -8,7 +8,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ClosedChannel } from '../../../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, CHANNEL_CLOSURE_TYPE, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, CHANNEL_CLOSURE_TYPE, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { CommonService } from '../../../../../shared/services/common.service';
@ -16,7 +16,8 @@ import { CommonService } from '../../../../../shared/services/common.service';
import { openAlert } from '../../../../../store/rtl.actions';
import { RTLState } from '../../../../../store/rtl.state';
import { closedChannels, lndPageSettings } from '../../../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-channel-closed-table',
@ -30,6 +31,8 @@ export class ChannelClosedTableComponent implements OnInit, AfterViewInit, OnDes
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'closed', recordsPerPage: PAGE_SIZE, sortBy: 'close_type', sortOrder: SortOrderEnum.DESCENDING };
@ -48,7 +51,7 @@ export class ChannelClosedTableComponent implements OnInit, AfterViewInit, OnDes
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -96,6 +99,38 @@ export class ChannelClosedTableComponent implements OnInit, AfterViewInit, OnDes
this.closedChannels.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.closedChannels.filterPredicate = (channel: ClosedChannel, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
// this.closedChannels.filterPredicate = (rowData: ClosedChannel, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
onClosedChannelClick(selChannel: ClosedChannel, event: any) {
const reorderedChannel = [
[{ key: 'close_type', value: this.channelClosureType[selChannel.close_type].name, title: 'Close Type', width: 30, type: DataTypeEnum.STRING },
@ -125,8 +160,8 @@ export class ChannelClosedTableComponent implements OnInit, AfterViewInit, OnDes
this.closedChannels.sort = this.sort;
this.closedChannels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.closedChannels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.closedChannels.filterPredicate = (channel: ClosedChannel, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
this.closedChannels.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.closedChannels);
}

@ -1,9 +1,16 @@
<div fxLayout="column" class="padding-gap-x">
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -25,7 +32,7 @@
<ng-container matColumnDef="remote_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.remote_alias || channel.remote_pubkey}}</span>
</div>
</td>
@ -33,7 +40,7 @@
<ng-container matColumnDef="remote_pubkey">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Pubkey</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.remote_pubkey}}</span>
</div>
</td>
@ -41,7 +48,7 @@
<ng-container matColumnDef="channel_point">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel Point</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel_point}}</span>
</div>
</td>
@ -49,7 +56,7 @@
<ng-container matColumnDef="chan_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.chan_id}}</span>
</div>
</td>

@ -12,7 +12,7 @@ import { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
import { ChannelInformationComponent } from '../../channel-information-modal/channel-information.component';
import { SelNodeChild } from '../../../../../shared/models/RTLconfig';
import { BlockchainBalance, Channel, ChannelsSummary, GetInfo, LightningBalance, Peer } from '../../../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, UserPersonaEnum, LoopTypeEnum, APICallStatusEnum, UI_MESSAGES, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, UserPersonaEnum, LoopTypeEnum, APICallStatusEnum, UI_MESSAGES, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { LoopService } from '../../../../../shared/services/loop.service';
@ -27,7 +27,8 @@ import { RTLState } from '../../../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../../../store/rtl.actions';
import { channelLookup, fetchChannels, updateChannel } from '../../../../store/lnd.actions';
import { blockchainBalance, channels, lndNodeInformation, lndNodeSettings, lndPageSettings, peers } from '../../../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-channel-open-table',
@ -41,6 +42,8 @@ export class ChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestr
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'open', recordsPerPage: PAGE_SIZE, sortBy: 'balancedness', sortOrder: SortOrderEnum.DESCENDING };
@ -68,7 +71,16 @@ export class ChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestr
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private lndEffects: LNDEffects, private commonService: CommonService, private rtlEffects: RTLEffects, private decimalPipe: DecimalPipe, private loopService: LoopService, private router: Router) {
constructor(
private logger: LoggerService,
private store: Store<RTLState>,
private lndEffects: LNDEffects,
private commonService: CommonService,
private rtlEffects: RTLEffects,
private decimalPipe: DecimalPipe,
private loopService: LoopService,
private router: Router,
private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
this.selFilter = this.router.getCurrentNavigation()?.extras?.state?.filter ? this.router.getCurrentNavigation()?.extras?.state?.filter : '';
}
@ -283,10 +295,6 @@ export class ChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestr
}));
}
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
onChannelClick(selChannel: Channel, event: any) {
this.store.dispatch(openAlert({
payload: {
@ -299,9 +307,16 @@ export class ChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestr
}));
}
loadChannelsTable(mychannels: Channel[]) {
mychannels.sort((a, b) => ((a.active === b.active) ? 0 : ((b.active) ? 1 : -1)));
this.channels = new MatTableDataSource<Channel>([...mychannels]);
applyFilter() {
this.channels.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.channels.filterPredicate = (channel: Channel, fltr: string) => {
const newChannel = ((channel.active) ? 'active' : 'inactive') + (channel.chan_id ? channel.chan_id.toLowerCase() : '') +
(channel.remote_pubkey ? channel.remote_pubkey.toLowerCase() : '') + (channel.remote_alias ? channel.remote_alias.toLowerCase() : '') +
@ -311,10 +326,38 @@ export class ChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestr
(channel.private ? 'private' : 'public');
return newChannel.includes(fltr);
};
// this.channels.filterPredicate = (rowData: Channel, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadChannelsTable(mychannels: Channel[]) {
this.channels = new MatTableDataSource<Channel>([...mychannels]);
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.channels.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.channels);
}

@ -12,7 +12,7 @@
<ng-container matColumnDef="remote_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.remote_alias}}</span>
</div>
</td>
@ -20,7 +20,7 @@
<ng-container matColumnDef="remote_node_pub">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Pubkey</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.remote_node_pub}}</span>
</div>
</td>
@ -28,7 +28,7 @@
<ng-container matColumnDef="channel_point">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel Point</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.channel_point}}</span>
</div>
</td>
@ -106,7 +106,7 @@
<ng-container matColumnDef="closing_txid">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Closing Tx ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.closing_txid}}</span>
</div>
</td>
@ -114,7 +114,7 @@
<ng-container matColumnDef="remote_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.remote_alias}}</span>
</div>
</td>
@ -122,7 +122,7 @@
<ng-container matColumnDef="remote_node_pub">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Pubkey</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.remote_node_pub}}</span>
</div>
</td>
@ -130,7 +130,7 @@
<ng-container matColumnDef="channel_point">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel Point</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.channel_point}}</span>
</div>
</td>
@ -202,7 +202,7 @@
<ng-container matColumnDef="closing_txid">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Closing Tx ID</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.closing_txid}}</span>
</div>
</td>
@ -210,7 +210,7 @@
<ng-container matColumnDef="remote_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.remote_alias}}</span>
</div>
</td>
@ -218,7 +218,7 @@
<ng-container matColumnDef="remote_node_pub">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Pubkey</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.remote_node_pub}}</span>
</div>
</td>
@ -226,7 +226,7 @@
<ng-container matColumnDef="channel_point">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel Point</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.channel_point}}</span>
</div>
</td>
@ -282,7 +282,7 @@
<ng-container matColumnDef="remote_alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.remote_alias}}</span>
</div>
</td>
@ -290,7 +290,7 @@
<ng-container matColumnDef="remote_node_pub">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Pubkey</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.remote_node_pub}}</span>
</div>
</td>
@ -298,7 +298,7 @@
<ng-container matColumnDef="channel_point">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel Point</th>
<td mat-cell *matCellDef="let channel">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{channel.channel.channel_point}}</span>
</div>
</td>

@ -28,11 +28,10 @@ export class ChannelPendingTableComponent implements OnInit, AfterViewInit, OnDe
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
public PAGE_ID = 'peers_channels';
public openTableSetting: TableSetting = { tableId: 'pending_open', recordsPerPage: PAGE_SIZE, sortBy: 'capacity', sortOrder: SortOrderEnum.DESCENDING };
public forceClosingopenTableSetting: TableSetting = { tableId: 'pending_force_closing', recordsPerPage: PAGE_SIZE, sortBy: 'limbo_balance', sortOrder: SortOrderEnum.DESCENDING };
public closingOpenTableSetting: TableSetting = { tableId: 'pending_closing', recordsPerPage: PAGE_SIZE, sortBy: 'capacity', sortOrder: SortOrderEnum.DESCENDING };
public waitingCloseopenTableSetting: TableSetting = { tableId: 'pending_waiting_close', recordsPerPage: PAGE_SIZE, sortBy: 'limbo_balance', sortOrder: SortOrderEnum.DESCENDING };
public forceClosingTableSetting: TableSetting = { tableId: 'pending_force_closing', recordsPerPage: PAGE_SIZE, sortBy: 'limbo_balance', sortOrder: SortOrderEnum.DESCENDING };
public closingTableSetting: TableSetting = { tableId: 'pending_closing', recordsPerPage: PAGE_SIZE, sortBy: 'capacity', sortOrder: SortOrderEnum.DESCENDING };
public waitingCloseTableSetting: TableSetting = { tableId: 'pending_waiting_close', recordsPerPage: PAGE_SIZE, sortBy: 'limbo_balance', sortOrder: SortOrderEnum.DESCENDING };
public selNode: SelNodeChild | null = {};
public selectedFilter = '';
public information: GetInfo = {};
public pendingChannels: PendingChannels = {};
public displayedOpenColumns: any[] = [];
@ -76,30 +75,30 @@ export class ChannelPendingTableComponent implements OnInit, AfterViewInit, OnDe
}
this.displayedOpenColumns.push('actions');
this.logger.info(this.displayedOpenColumns);
this.forceClosingopenTableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.forceClosingopenTableSetting.tableId) ||
LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.forceClosingopenTableSetting.tableId)!;
this.forceClosingTableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.forceClosingTableSetting.tableId) ||
LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.forceClosingTableSetting.tableId)!;
if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedForceClosingColumns = JSON.parse(JSON.stringify(this.forceClosingopenTableSetting.columnSelectionSM));
this.displayedForceClosingColumns = JSON.parse(JSON.stringify(this.forceClosingTableSetting.columnSelectionSM));
} else {
this.displayedForceClosingColumns = JSON.parse(JSON.stringify(this.forceClosingopenTableSetting.columnSelection));
this.displayedForceClosingColumns = JSON.parse(JSON.stringify(this.forceClosingTableSetting.columnSelection));
}
this.displayedForceClosingColumns.push('actions');
this.logger.info(this.displayedForceClosingColumns);
this.closingOpenTableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.closingOpenTableSetting.tableId) ||
LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.closingOpenTableSetting.tableId)!;
this.closingTableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.closingTableSetting.tableId) ||
LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.closingTableSetting.tableId)!;
if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedClosingColumns = JSON.parse(JSON.stringify(this.closingOpenTableSetting.columnSelectionSM));
this.displayedClosingColumns = JSON.parse(JSON.stringify(this.closingTableSetting.columnSelectionSM));
} else {
this.displayedClosingColumns = JSON.parse(JSON.stringify(this.closingOpenTableSetting.columnSelection));
this.displayedClosingColumns = JSON.parse(JSON.stringify(this.closingTableSetting.columnSelection));
}
this.displayedClosingColumns.push('actions');
this.logger.info(this.displayedClosingColumns);
this.waitingCloseopenTableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.waitingCloseopenTableSetting.tableId) ||
LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.waitingCloseopenTableSetting.tableId)!;
this.waitingCloseTableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.waitingCloseTableSetting.tableId) ||
LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.waitingCloseTableSetting.tableId)!;
if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedWaitClosingColumns = JSON.parse(JSON.stringify(this.waitingCloseopenTableSetting.columnSelectionSM));
this.displayedWaitClosingColumns = JSON.parse(JSON.stringify(this.waitingCloseTableSetting.columnSelectionSM));
} else {
this.displayedWaitClosingColumns = JSON.parse(JSON.stringify(this.waitingCloseopenTableSetting.columnSelection));
this.displayedWaitClosingColumns = JSON.parse(JSON.stringify(this.waitingCloseTableSetting.columnSelection));
}
this.displayedWaitClosingColumns.push('actions');
this.logger.info(this.displayedWaitClosingColumns);
@ -264,42 +263,38 @@ export class ChannelPendingTableComponent implements OnInit, AfterViewInit, OnDe
}
loadOpenChannelsTable(channels) {
channels.sort((a, b) => ((a.active === b.active) ? 0 : ((b.active) ? -1 : 1)));
this.pendingOpenChannelsLength = (channels.length) ? channels.length : 0;
this.pendingOpenChannels = new MatTableDataSource<Channel>([...channels]);
this.pendingOpenChannels.sort = this.sort;
this.pendingOpenChannels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.pendingOpenChannels.filterPredicate = (channel: any, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
this.pendingOpenChannels.sort?.sort({ id: this.openTableSetting.sortBy, start: this.openTableSetting.sortOrder, disableClear: true });
this.logger.info(this.pendingOpenChannels);
}
loadForceClosingChannelsTable(channels) {
channels.sort((a, b) => ((a.active === b.active) ? 0 : ((b.active) ? -1 : 1)));
this.pendingForceClosingChannelsLength = (channels.length) ? channels.length : 0;
this.pendingForceClosingChannels = new MatTableDataSource<Channel>([...channels]);
this.pendingForceClosingChannels.sort = this.sort;
this.pendingForceClosingChannels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.pendingForceClosingChannels.filterPredicate = (channel: any, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
this.pendingForceClosingChannels.sort?.sort({ id: this.forceClosingTableSetting.sortBy, start: this.forceClosingTableSetting.sortOrder, disableClear: true });
this.logger.info(this.pendingForceClosingChannels);
}
loadClosingChannelsTable(channels) {
channels.sort((a, b) => ((a.active === b.active) ? 0 : ((b.active) ? -1 : 1)));
this.pendingClosingChannelsLength = (channels.length) ? channels.length : 0;
this.pendingClosingChannels = new MatTableDataSource<Channel>([...channels]);
this.pendingClosingChannels.sort = this.sort;
this.pendingClosingChannels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.pendingClosingChannels.filterPredicate = (channel: any, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
this.pendingClosingChannels.sort?.sort({ id: this.closingTableSetting.sortBy, start: this.closingTableSetting.sortOrder, disableClear: true });
this.logger.info(this.pendingClosingChannels);
}
loadWaitClosingChannelsTable(channels) {
channels.sort((a, b) => ((a.active === b.active) ? 0 : ((b.active) ? -1 : 1)));
this.pendingWaitClosingChannelsLength = (channels.length) ? channels.length : 0;
this.pendingWaitClosingChannels = new MatTableDataSource<Channel>([...channels]);
this.pendingWaitClosingChannels.sort = this.sort;
this.pendingWaitClosingChannels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.pendingWaitClosingChannels.filterPredicate = (channel: any, fltr: string) => JSON.stringify(channel).toLowerCase().includes(fltr);
this.pendingWaitClosingChannels.sort?.sort({ id: this.waitingCloseTableSetting.sortBy, start: this.waitingCloseTableSetting.sortOrder, disableClear: true });
this.logger.info(this.pendingWaitClosingChannels);
}

@ -8,9 +8,16 @@
<fa-icon [icon]="faUsers" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Connected Peers</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -18,7 +25,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Alias</th>
<td mat-cell *matCellDef="let peer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{peer?.alias}}</span>
</div>
</td>
@ -26,7 +33,7 @@
<ng-container matColumnDef="pub_key">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Public Key</th>
<td mat-cell *matCellDef="let peer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{peer?.pub_key}}</span>
</div>
</td>
@ -34,7 +41,7 @@
<ng-container matColumnDef="address">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Address</th>
<td mat-cell *matCellDef="let peer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{peer?.address}}</span>
</div>
</td>

@ -8,7 +8,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Peer, GetInfo, BlockchainBalance } from '../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -20,7 +20,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../store/rtl.actions';
import { detachPeer } from '../../store/lnd.actions';
import { blockchainBalance, lndNodeInformation, lndPageSettings, peers } from '../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-peers',
@ -34,6 +35,8 @@ export class PeersComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'peers_channels';
public tableSetting: TableSetting = { tableId: 'peers', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };
@ -53,7 +56,7 @@ export class PeersComponent implements OnInit, AfterViewInit, OnDestroy {
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -177,13 +180,45 @@ export class PeersComponent implements OnInit, AfterViewInit, OnDestroy {
this.peers.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.peers.filterPredicate = (peer: Peer, fltr: string) => JSON.stringify(peer).toLowerCase().includes(fltr);
// this.peers.filterPredicate = (rowData: Peer, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadPeersTable(peers: Peer[]) {
this.peers = peers ? new MatTableDataSource<Peer>([...peers]) : new MatTableDataSource([]);
this.peers.sort = this.sort;
this.peers.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.peers.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.peers.filterPredicate = (peer: Peer, fltr: string) => JSON.stringify(peer).toLowerCase().includes(fltr);
this.peers.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}

@ -41,7 +41,7 @@
</div>
<div fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100" class="padding-gap-x">
<div class="mt-1">
<rtl-forwarding-history *ngIf="events && events?.forwarding_events && events.forwarding_events.length && events.forwarding_events.length > 0" [pageId]="'reports'" [tableId]="'routing'" [eventsData]="events?.forwarding_events" [filterValue]="eventFilterValue"></rtl-forwarding-history>
<rtl-forwarding-history *ngIf="events && events?.forwarding_events && events.forwarding_events.length && events.forwarding_events.length > 0" [pageId]="'reports'" [tableId]="'routing'" [eventsData]="events?.forwarding_events" [selFilter]="eventFilterValue"></rtl-forwarding-history>
</div>
</div>
</div>

@ -41,7 +41,7 @@
</ngx-charts-bar-vertical-2d>
</div>
<div class="mt-1">
<rtl-transactions-report-table *ngIf="transactionsNonZeroReportData.length > 0 && apiCallStatus.status === apiCallStatusEnum.COMPLETED" [displayedColumns]="displayedColumns" [tableSetting]="tableSetting" [dataList]="transactionsNonZeroReportData" [dataRange]="reportPeriod" [filterValue]="transactionFilterValue"></rtl-transactions-report-table>
<rtl-transactions-report-table *ngIf="transactionsNonZeroReportData.length > 0 && apiCallStatus.status === apiCallStatusEnum.COMPLETED" [displayedColumns]="displayedColumns" [tableSetting]="tableSetting" [dataList]="transactionsNonZeroReportData" [dataRange]="reportPeriod" [selFilter]="transactionFilterValue"></rtl-transactions-report-table>
</div>
</div>
</div>

@ -2,9 +2,16 @@
<div class="p-2 error-border my-2" *ngIf="errorMessage !== ''">{{errorMessage}}</div>
<div *ngIf="errorMessage === ''" fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30">
<input matInput [(ngModel)]="filterValue" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div *ngIf="errorMessage === ''" [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -16,7 +23,7 @@
<ng-container matColumnDef="alias_in">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Inbound Alias</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.alias_in}}</span>
</div>
</td>
@ -24,7 +31,7 @@
<ng-container matColumnDef="chan_id_in">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Inbound Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.chan_id_in}}</span>
</div>
</td>
@ -32,7 +39,7 @@
<ng-container matColumnDef="alias_out">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Outbound Alias</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.alias_out}}</span>
</div>
</td>
@ -40,7 +47,7 @@
<ng-container matColumnDef="chan_id_out">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Outbound Channel</th>
<td mat-cell *matCellDef="let fhEvent">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{fhEvent?.chan_id_out}}</span>
</div>
</td>

@ -8,7 +8,7 @@ import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { ForwardingEvent, SwitchRes } from '../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -16,7 +16,8 @@ import { openAlert } from '../../../store/rtl.actions';
import { RTLState } from '../../../store/rtl.state';
import { forwardingHistory, lndPageSettings } from '../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-forwarding-history',
@ -33,7 +34,9 @@ export class ForwardingHistoryComponent implements OnInit, AfterViewInit, OnChan
@Input() pageId = 'routing';
@Input() tableId = 'forwarding_history';
@Input() eventsData = [];
@Input() filterValue = '';
@Input() selFilter = '';
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'routing';
public tableSetting: TableSetting = { tableId: 'forwarding_history', recordsPerPage: PAGE_SIZE, sortBy: 'timestamp', sortOrder: SortOrderEnum.DESCENDING };
@ -49,7 +52,7 @@ export class ForwardingHistoryComponent implements OnInit, AfterViewInit, OnChan
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -104,7 +107,7 @@ export class ForwardingHistoryComponent implements OnInit, AfterViewInit, OnChan
this.loadForwardingEventsTable(this.forwardingHistoryData);
}
}
if (changes.filterValue && !changes.filterValue.firstChange) {
if (changes.selFilter && !changes.selFilter.firstChange) {
this.applyFilter();
}
}
@ -131,16 +134,55 @@ export class ForwardingHistoryComponent implements OnInit, AfterViewInit, OnChan
}));
}
applyFilter() {
if (this.forwardingHistoryEvents) {
this.forwardingHistoryEvents.filter = this.selFilter.trim().toLowerCase();
}
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.forwardingHistoryEvents.filterPredicate = (rowData: ForwardingEvent, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.forwardingHistoryEvents.filterPredicate = (rowData: ForwardingEvent, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadForwardingEventsTable(forwardingEvents: ForwardingEvent[]) {
this.forwardingHistoryEvents = forwardingEvents ? new MatTableDataSource<ForwardingEvent>([...forwardingEvents]) : new MatTableDataSource([]);
this.forwardingHistoryEvents.sort = this.sort;
this.forwardingHistoryEvents.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.forwardingHistoryEvents.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.forwardingHistoryEvents.filterPredicate = (rowData: ForwardingEvent, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.forwardingHistoryEvents.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.forwardingHistoryEvents);
}
@ -150,12 +192,6 @@ export class ForwardingHistoryComponent implements OnInit, AfterViewInit, OnChan
}
}
applyFilter() {
if (this.forwardingHistoryEvents) {
this.forwardingHistoryEvents.filter = this.filterValue.trim().toLowerCase();
}
}
ngOnDestroy() {
this.unSubs.forEach((completeSub) => {
completeSub.next(<any>null);

@ -3,13 +3,20 @@
<div *ngIf="errorMessage === ''" fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch">
<div *ngIf="errorMessage === ''" fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70">Non Routing Peers</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div *ngIf="errorMessage === ''" [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<table mat-table #table [dataSource]="NonRoutingPeers" matSort class="overflow-auto">
<table mat-table #table [dataSource]="nonRoutingPeers" matSort class="overflow-auto">
<ng-container matColumnDef="chan_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let nonRPeer">
@ -110,12 +117,12 @@
</ng-container>
<ng-container matColumnDef="no_non_routing_event">
<td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="(!NonRoutingPeers?.data || NonRoutingPeers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">All peers are routing.</p>
<p *ngIf="(!NonRoutingPeers?.data || NonRoutingPeers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting non routing peers...</p>
<p *ngIf="(!NonRoutingPeers?.data || NonRoutingPeers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
<p *ngIf="(!nonRoutingPeers?.data || nonRoutingPeers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">All peers are routing.</p>
<p *ngIf="(!nonRoutingPeers?.data || nonRoutingPeers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting non routing peers...</p>
<p *ngIf="(!nonRoutingPeers?.data || nonRoutingPeers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="['no_non_routing_event']" [ngClass]="{'display-none': NonRoutingPeers?.data?.length>0}"></tr>
<tr mat-footer-row *matFooterRowDef="['no_non_routing_event']" [ngClass]="{'display-none': nonRoutingPeers?.data?.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

@ -8,14 +8,15 @@ import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { ForwardingEvent, SwitchRes, Channel, ChannelsSummary, LightningBalance } from '../../../shared/models/lndModels';
import { APICallStatusEnum, getPaginatorLabel, LND_DEFAULT_PAGE_SETTINGS, PAGE_SIZE, PAGE_SIZE_OPTIONS, ScreenSizeEnum, SortOrderEnum } from '../../../shared/services/consts-enums-functions';
import { APICallStatusEnum, getPaginatorLabel, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS, PAGE_SIZE, PAGE_SIZE_OPTIONS, ScreenSizeEnum, SortOrderEnum } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
import { RTLState } from '../../../store/rtl.state';
import { channels, forwardingHistory, lndPageSettings } from '../../store/lnd.selector';
import { ActivatedRoute, Router } from '@angular/router';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-non-routing-peers',
@ -29,25 +30,27 @@ export class NonRoutingPeersComponent implements OnInit, AfterViewInit, OnDestro
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'routing';
public tableSetting: TableSetting = { tableId: 'non_routing_peers', recordsPerPage: PAGE_SIZE, sortBy: 'remote_alias', sortOrder: SortOrderEnum.DESCENDING };
public routingPeersData: any[] = [];
public displayedColumns: any[] = [];
public NonRoutingPeers: any = new MatTableDataSource<any>([]);
public nonRoutingPeers: any = new MatTableDataSource<any>([]);
public pageSize = PAGE_SIZE;
public pageSizeOptions = PAGE_SIZE_OPTIONS;
public screenSize = '';
public screenSizeEnum = ScreenSizeEnum;
public errorMessage = '';
public filter = '';
public selFilter = '';
public activeChannels: Channel[] = [];
public timeUnit = 'mins:secs';
public apiCallStatus: ApiCallStatusPayload | null = null;
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private router: Router, private activatedRoute: ActivatedRoute, private decimalPipe: DecimalPipe) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private router: Router, private activatedRoute: ActivatedRoute, private decimalPipe: DecimalPipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -186,26 +189,59 @@ export class NonRoutingPeersComponent implements OnInit, AfterViewInit, OnDestro
// return this.commonService.sortDescByKey(results, 'alias');
// }
applyFilter() {
this.nonRoutingPeers.filter = this.selFilter.toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.nonRoutingPeers.filterPredicate = (nrchnl: Channel, fltr: string) => JSON.stringify(nrchnl).toLowerCase().includes(fltr);
// this.peers.filterPredicate = (rowData: Peer, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadNonRoutingPeersTable(forwardingEvents: ForwardingEvent[]) {
if (forwardingEvents.length > 0) {
// const grpdRoutingPeers = this.groupRoutingPeers(forwardingEvents);
const filteredNonRoutingChannels = this.calculateUptime(this.activeChannels?.filter((actvChnl) => forwardingEvents.findIndex((evnt) => (evnt.chan_id_in === actvChnl.chan_id || evnt.chan_id_out === actvChnl.chan_id)) < 0));
this.NonRoutingPeers = new MatTableDataSource<Channel>(filteredNonRoutingChannels);
this.NonRoutingPeers.sort = this.sort;
this.NonRoutingPeers.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.NonRoutingPeers.filterPredicate = (nrchnl: Channel, fltr: string) => JSON.stringify(nrchnl).toLowerCase().includes(fltr);
this.NonRoutingPeers.paginator = this.paginator;
this.logger.info(this.NonRoutingPeers);
this.nonRoutingPeers = new MatTableDataSource<Channel>(filteredNonRoutingChannels);
this.nonRoutingPeers.sort = this.sort;
this.nonRoutingPeers.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.nonRoutingPeers.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.nonRoutingPeers);
} else {
this.NonRoutingPeers = new MatTableDataSource<Channel>([]);
this.nonRoutingPeers = new MatTableDataSource<Channel>([]);
}
this.applyFilter();
}
applyFilter() {
this.NonRoutingPeers.filter = this.filter.toLowerCase();
}
ngOnDestroy() {
this.unSubs.forEach((completeSub) => {
completeSub.next(<any>null);

@ -4,17 +4,24 @@
<div fxLayout="column" fxFlex="49" fxLayoutAlign="start stretch" class="mb-4">
<div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="page-sub-title-container w-100" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS, 'mt-1': screenSize === screenSizeEnum.SM}">
<div fxFlex="70">Incoming</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyIncomingFilter()" [(ngModel)]="filterIn" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterByIn" (selectionChange)="selFilterIn=''; applyIncomingFilter()" name="filterByIn">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilterIn" (input)="applyIncomingFilter()" (keyup)="applyIncomingFilter()" name="filterin" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start start" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<table mat-table #tableIn [dataSource]="RoutingPeersIncoming" matSort class="overflow-auto incoming-table">
<table mat-table #tableIn [dataSource]="routingPeersIncoming" matSort class="overflow-auto incoming-table">
<ng-container matColumnDef="chan_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer?.chan_id}}</span>
</div>
</td>
@ -22,7 +29,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer?.alias}}</span>
</div>
</td>
@ -46,12 +53,12 @@
</ng-container>
<ng-container matColumnDef="no_incoming_event">
<td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">No incoming routing peer available.</p>
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting incoming routing peers...</p>
<p *ngIf="(!RoutingPeersIncoming?.data || RoutingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">No incoming routing peer available.</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting incoming routing peers...</p>
<p *ngIf="(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="['no_incoming_event']" [ngClass]="{'display-none': RoutingPeersIncoming?.data?.length>0}"></tr>
<tr mat-footer-row *matFooterRowDef="['no_incoming_event']" [ngClass]="{'display-none': routingPeersIncoming?.data?.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
@ -61,17 +68,24 @@
<div fxLayout="column" fxFlex="49" fxLayoutAlign="start stretch" class="mb-4">
<div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="page-sub-title-container w-100" [ngClass]="{'mt-2': screenSize !== screenSizeEnum.LG}">
<div fxFlex="70">Outgoing</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyOutgoingFilter()" [(ngModel)]="filterOut" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterByOut" (selectionChange)="selFilterOut=''; applyOutgoingFilter()" name="filterByOut">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilterOut" (input)="applyOutgoingFilter()" (keyup)="applyOutgoingFilter()" name="filterout" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start start" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<table mat-table #tableOut [dataSource]="RoutingPeersOutgoing" matSort class="overflow-auto outgoing-table">
<table mat-table #tableOut [dataSource]="routingPeersOutgoing" matSort class="overflow-auto outgoing-table">
<ng-container matColumnDef="chan_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer?.chan_id}}</span>
</div>
</td>
@ -79,7 +93,7 @@
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th>
<td mat-cell *matCellDef="let rPeer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{rPeer?.alias}}</span>
</div>
</td>
@ -95,12 +109,12 @@
</ng-container>
<ng-container matColumnDef="no_outgoing_event">
<td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">No outgoing routing peer available.</p>
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting outgoing routing peers...</p>
<p *ngIf="(!RoutingPeersOutgoing?.data || RoutingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED">No outgoing routing peer available.</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED">Getting outgoing routing peers...</p>
<p *ngIf="(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR">{{errorMessage}}</p>
</td>
</ng-container>
<tr mat-footer-row *matFooterRowDef="['no_outgoing_event']" [ngClass]="{'display-none': RoutingPeersOutgoing?.data?.length>0}"></tr>
<tr mat-footer-row *matFooterRowDef="['no_outgoing_event']" [ngClass]="{'display-none': routingPeersOutgoing?.data?.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

@ -7,7 +7,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { ForwardingEvent, RoutingPeers, SwitchRes } from '../../../shared/models/lndModels';
import { AlertTypeEnum, APICallStatusEnum, DataTypeEnum, getPaginatorLabel, LND_DEFAULT_PAGE_SETTINGS, PAGE_SIZE, PAGE_SIZE_OPTIONS, ScreenSizeEnum, SortOrderEnum } from '../../../shared/services/consts-enums-functions';
import { AlertTypeEnum, APICallStatusEnum, DataTypeEnum, getPaginatorLabel, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS, PAGE_SIZE, PAGE_SIZE_OPTIONS, ScreenSizeEnum, SortOrderEnum } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -15,6 +15,7 @@ import { openAlert } from '../../../store/rtl.actions';
import { RTLState } from '../../../store/rtl.state';
import { forwardingHistory, lndPageSettings } from '../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-routing-peers',
@ -30,13 +31,16 @@ export class RoutingPeersComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('tableOut', { read: MatSort, static: false }) sortOut: MatSort;
@ViewChild('paginatorIn', { static: false }) paginatorIn: MatPaginator | undefined;
@ViewChild('paginatorOut', { static: false }) paginatorOut: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterByIn = 'all';
public selFilterByOut = 'all';
public colWidth = '20rem';
public PAGE_ID = 'routing';
public tableSetting: TableSetting = { tableId: 'routing_peers', recordsPerPage: PAGE_SIZE, sortBy: 'total_amount', sortOrder: SortOrderEnum.DESCENDING };
public routingPeersData: any[] = [];
public displayedColumns: any[] = [];
public RoutingPeersIncoming = new MatTableDataSource<RoutingPeers>([]);
public RoutingPeersOutgoing = new MatTableDataSource<RoutingPeers>([]);
public routingPeersIncoming = new MatTableDataSource<RoutingPeers>([]);
public routingPeersOutgoing = new MatTableDataSource<RoutingPeers>([]);
public pageSize = PAGE_SIZE;
public pageSizeOptions = PAGE_SIZE_OPTIONS;
public screenSize = '';
@ -48,7 +52,7 @@ export class RoutingPeersComponent implements OnInit, AfterViewInit, OnDestroy {
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -123,22 +127,22 @@ export class RoutingPeersComponent implements OnInit, AfterViewInit, OnDestroy {
loadRoutingPeersTable(forwardingEvents: ForwardingEvent[]) {
if (forwardingEvents.length > 0) {
const results = this.groupRoutingPeers(forwardingEvents);
this.RoutingPeersIncoming = new MatTableDataSource<RoutingPeers>(results[0]);
this.RoutingPeersIncoming.sort = this.sortIn;
this.RoutingPeersIncoming.sort.sort({ id: this.tableSetting.sortBy || 'total_amount', start: this.tableSetting.sortOrder || SortOrderEnum.DESCENDING, disableClear: true });
this.RoutingPeersIncoming.filterPredicate = (rpIn: RoutingPeers, fltr: string) => JSON.stringify(rpIn).toLowerCase().includes(fltr);
this.RoutingPeersIncoming.paginator = this.paginatorIn!;
this.logger.info(this.RoutingPeersIncoming);
this.RoutingPeersOutgoing = new MatTableDataSource<RoutingPeers>(results[1]);
this.RoutingPeersOutgoing.sort = this.sortOut;
this.RoutingPeersOutgoing.sort.sort({ id: this.tableSetting.sortBy || 'total_amount', start: this.tableSetting.sortOrder || SortOrderEnum.DESCENDING, disableClear: true });
this.RoutingPeersOutgoing.filterPredicate = (rpOut: RoutingPeers, fltr: string) => JSON.stringify(rpOut).toLowerCase().includes(fltr);
this.RoutingPeersOutgoing.paginator = this.paginatorOut!;
this.logger.info(this.RoutingPeersOutgoing);
this.routingPeersIncoming = new MatTableDataSource<RoutingPeers>(results[0]);
this.routingPeersIncoming.sort = this.sortIn;
this.routingPeersIncoming.sort.sort({ id: this.tableSetting.sortBy || 'total_amount', start: this.tableSetting.sortOrder || SortOrderEnum.DESCENDING, disableClear: true });
this.routingPeersIncoming.filterPredicate = (rpIn: RoutingPeers, fltr: string) => JSON.stringify(rpIn).toLowerCase().includes(fltr);
this.routingPeersIncoming.paginator = this.paginatorIn!;
this.logger.info(this.routingPeersIncoming);
this.routingPeersOutgoing = new MatTableDataSource<RoutingPeers>(results[1]);
this.routingPeersOutgoing.sort = this.sortOut;
this.routingPeersOutgoing.sort.sort({ id: this.tableSetting.sortBy || 'total_amount', start: this.tableSetting.sortOrder || SortOrderEnum.DESCENDING, disableClear: true });
this.routingPeersOutgoing.filterPredicate = (rpOut: RoutingPeers, fltr: string) => JSON.stringify(rpOut).toLowerCase().includes(fltr);
this.routingPeersOutgoing.paginator = this.paginatorOut!;
this.logger.info(this.routingPeersOutgoing);
} else {
// To reset table after other Forwarding history calls
this.RoutingPeersIncoming = new MatTableDataSource<RoutingPeers>([]);
this.RoutingPeersOutgoing = new MatTableDataSource<RoutingPeers>([]);
this.routingPeersIncoming = new MatTableDataSource<RoutingPeers>([]);
this.routingPeersOutgoing = new MatTableDataSource<RoutingPeers>([]);
}
this.applyIncomingFilter();
this.applyOutgoingFilter();
@ -167,11 +171,11 @@ export class RoutingPeersComponent implements OnInit, AfterViewInit, OnDestroy {
}
applyIncomingFilter() {
this.RoutingPeersIncoming.filter = this.filterIn.toLowerCase();
this.routingPeersIncoming.filter = this.filterIn.toLowerCase();
}
applyOutgoingFilter() {
this.RoutingPeersOutgoing.filter = this.filterOut.toLowerCase();
this.routingPeersOutgoing.filter = this.filterOut.toLowerCase();
}
ngOnDestroy() {

@ -22,9 +22,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Invoices History</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" tabindex="6" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start end" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
@ -70,7 +77,7 @@
<ng-container matColumnDef="memo">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Memo</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.memo}}</span>
</div>
</td>
@ -78,7 +85,7 @@
<ng-container matColumnDef="r_preimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Preimage</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.r_preimage}}</span>
</div>
</td>
@ -86,7 +93,7 @@
<ng-container matColumnDef="r_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Preimage Hash</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.r_hash}}</span>
</div>
</td>
@ -94,7 +101,7 @@
<ng-container matColumnDef="payment_addr">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Address</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.payment_addr}}</span>
</div>
</td>
@ -102,7 +109,7 @@
<ng-container matColumnDef="payment_request">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Request</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.payment_request}}</span>
</div>
</td>
@ -110,7 +117,7 @@
<ng-container matColumnDef="description_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description Hash</th>
<td mat-cell *matCellDef="let invoice">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<div class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{invoice?.description_hash}}</span>
</div>
</td>

@ -9,7 +9,7 @@ import { MatPaginator, MatPaginatorIntl, PageEvent } from '@angular/material/pag
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, UI_MESSAGES, LNDActions, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../shared/services/consts-enums-functions';
import { CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, UI_MESSAGES, LNDActions, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { SelNodeChild } from '../../../shared/models/RTLconfig';
import { GetInfo, Invoice, ListInvoices } from '../../../shared/models/lndModels';
@ -23,7 +23,8 @@ import { RTLState } from '../../../store/rtl.state';
import { openAlert } from '../../../store/rtl.actions';
import { fetchInvoices, invoiceLookup, saveNewInvoice } from '../../store/lnd.actions';
import { invoices, lndNodeInformation, lndNodeSettings, lndPageSettings } from '../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-lightning-invoices',
@ -45,6 +46,8 @@ export class LightningInvoicesComponent implements OnInit, AfterViewInit, OnDest
public faArrowsTurnRight = faArrowsTurnRight;
public faBurst = faBurst;
public faMoneyBill1 = faMoneyBill1;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'invoices', recordsPerPage: PAGE_SIZE, sortBy: 'creation_date', sortOrder: SortOrderEnum.DESCENDING };
@ -75,7 +78,7 @@ export class LightningInvoicesComponent implements OnInit, AfterViewInit, OnDest
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private datePipe: DatePipe, private actions: Actions) {
constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private datePipe: DatePipe, private actions: Actions, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -169,16 +172,53 @@ export class LightningInvoicesComponent implements OnInit, AfterViewInit, OnDest
this.invoicesData = this.invoicesData?.map((invoice) => ((invoice.r_hash === newInvoice.r_hash) ? newInvoice : invoice));
}
loadInvoicesTable(invoices) {
this.invoices = invoices ? new MatTableDataSource<Invoice>([...invoices]) : new MatTableDataSource<Invoice>([]);
this.invoices.sort = this.sort;
this.invoices.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.invoices.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
applyFilter() {
this.invoices.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.invoices.filterPredicate = (invoice: Invoice, fltr: string) => {
const newInvoice = (invoice.creation_date ? this.datePipe.transform(new Date(invoice.creation_date * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '')! +
(invoice.settle_date ? this.datePipe.transform(new Date(invoice.settle_date * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(invoice).toLowerCase();
return newInvoice.includes(fltr);
};
// this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadInvoicesTable(invoices) {
this.invoices = invoices ? new MatTableDataSource<Invoice>([...invoices]) : new MatTableDataSource<Invoice>([]);
this.invoices.sort = this.sort;
this.invoices.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.invoices.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.invoices);
}
@ -191,10 +231,6 @@ export class LightningInvoicesComponent implements OnInit, AfterViewInit, OnDest
this.invoiceValueHint = '';
}
applyFilter() {
this.invoices.filter = this.selFilter.trim().toLowerCase();
}
onPageChange(event: PageEvent) {
let reverse = true;
let index_offset = this.lastOffset;

@ -19,9 +19,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Payments History</span>
</div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start start">
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start end" fxFlex="100" class="table-container">
@ -43,7 +50,7 @@
<ng-container matColumnDef="payment_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.payment_hash}}</span>
</span>
</td>
@ -51,7 +58,7 @@
<ng-container matColumnDef="payment_request">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Request</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.payment_request}}</span>
</span>
</td>
@ -59,7 +66,7 @@
<ng-container matColumnDef="payment_preimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Preimage</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.payment_preimage}}</span>
</span>
</td>
@ -67,7 +74,7 @@
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.description}}</span>
</span>
</td>
@ -75,7 +82,7 @@
<ng-container matColumnDef="description_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description Hash</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.description_hash}}</span>
</span>
</td>
@ -151,7 +158,7 @@
</ng-container>
<ng-container matColumnDef="group_payment_hash">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.payment_hash}}</span>
</span>
<span *ngIf="payment?.is_expanded">
@ -163,7 +170,7 @@
</ng-container>
<ng-container matColumnDef="group_payment_request">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.payment_request}}</span>
</span>
<span *ngIf="payment?.is_expanded">
@ -174,7 +181,7 @@
</ng-container>
<ng-container matColumnDef="group_payment_preimage">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.payment_preimage}}</span>
</span>
<span *ngIf="payment?.is_expanded">
@ -186,7 +193,7 @@
</ng-container>
<ng-container matColumnDef="group_description">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.description}}</span>
</span>
<span *ngIf="payment?.is_expanded">
@ -197,7 +204,7 @@
</ng-container>
<ng-container matColumnDef="group_description_hash">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{payment?.description_hash}}</span>
</span>
<span *ngIf="payment?.is_expanded">

@ -8,8 +8,8 @@ import { faHistory } from '@fortawesome/free-solid-svg-icons';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { GetInfo, Payment, PayRequest, PaymentHTLC, Peer, Hop, ListPayments, ListInvoices } from '../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, APICallStatusEnum, UI_MESSAGES, LND_DEFAULT_PAGE_SETTINGS, SortOrderEnum } from '../../../shared/services/consts-enums-functions';
import { GetInfo, Payment, PayRequest, PaymentHTLC, Peer, Hop, ListPayments } from '../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, APICallStatusEnum, UI_MESSAGES, LND_DEFAULT_PAGE_SETTINGS, SortOrderEnum, LND_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
import { DataService } from '../../../shared/services/data.service';
@ -18,13 +18,13 @@ import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { SelNodeChild } from '../../../shared/models/RTLconfig';
import { LightningSendPaymentsComponent } from '../send-payment-modal/send-payment.component';
import { LNDEffects } from '../../store/lnd.effects';
import { RTLEffects } from '../../../store/rtl.effects';
import { RTLState } from '../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../store/rtl.actions';
import { sendPayment } from '../../store/lnd.actions';
import { lndNodeInformation, lndNodeSettings, lndPageSettings, payments, peers } from '../../store/lnd.selector';
import { PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithReplacePipe } from '../../../shared/pipes/app.pipe';
@Component({
selector: 'rtl-lightning-payments',
@ -41,6 +41,8 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faHistory = faHistory;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'creation_date', sortOrder: SortOrderEnum.DESCENDING };
@ -68,7 +70,7 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private dataService: DataService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private lndEffects: LNDEffects, private decimalPipe: DecimalPipe, private datePipe: DatePipe) {
constructor(private logger: LoggerService, private commonService: CommonService, private dataService: DataService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private decimalPipe: DecimalPipe, private datePipe: DatePipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -432,6 +434,41 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
this.payments.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.payments.filterPredicate = (payment: Payment, fltr: string) => {
const newPayment = ((payment.creation_date) ? this.datePipe.transform(new Date(payment.creation_date * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(payment).toLowerCase();
return newPayment.includes(fltr);
};
// this.channels.filterPredicate = (rowData: Channel, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadPaymentsTable(payms) {
this.payments = payms ? new MatTableDataSource<Payment>([...payms]) : new MatTableDataSource([]);
this.payments.sortingDataAccessor = (data: any, sortHeaderId: string) => {
@ -445,10 +482,7 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
};
this.payments.sort = this.sort;
this.payments.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.payments.filterPredicate = (payment: Payment, fltr: string) => {
const newPayment = ((payment.creation_date) ? this.datePipe.transform(new Date(payment.creation_date * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(payment).toLowerCase();
return newPayment.includes(fltr);
};
this.setFilterPredicate();
this.applyFilter();
}

@ -4,9 +4,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">{{swapCaption}} History</span>
</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start center" class="w-100">
<div [perfectScrollbar] class="table-container" fxFlex="100">
@ -23,7 +30,7 @@
<ng-container matColumnDef="claimAddress">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Claim Address</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.claimAddress}}</span>
</span>
</td>
@ -31,7 +38,7 @@
<ng-container matColumnDef="lockupAddress">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Lockup Address</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.lockupAddress}}</span>
</span>
</td>
@ -51,7 +58,7 @@
<ng-container matColumnDef="error">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Error</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.error}}</span>
</span>
</td>
@ -59,7 +66,7 @@
<ng-container matColumnDef="privateKey">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Private Key</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.privateKey}}</span>
</span>
</td>
@ -67,7 +74,7 @@
<ng-container matColumnDef="preimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Preimage</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.preimage}}</span>
</span>
</td>
@ -75,7 +82,7 @@
<ng-container matColumnDef="redeemScript">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Redeem Script</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.redeemScript}}</span>
</span>
</td>
@ -83,7 +90,7 @@
<ng-container matColumnDef="invoice">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Invoice</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.invoice}}</span>
</span>
</td>

@ -8,16 +8,17 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { Swap, ReverseSwap } from '../../../../models/boltzModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, SwapTypeEnum, SwapStateEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../../services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, SwapTypeEnum, SwapStateEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../../services/consts-enums-functions';
import { LoggerService } from '../../../../services/logger.service';
import { CommonService } from '../../../../services/common.service';
import { BoltzService } from '../../../../services/boltz.service';
import { openAlert } from '../../../../../store/rtl.actions';
import { RTLState } from '../../../../../store/rtl.state';
import { PageSettings, TableSetting } from '../../../../models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../models/pageSettings';
import { lndPageSettings } from '../../../../../lnd/store/lnd.selector';
import { ApiCallStatusPayload } from '../../../../models/apiCallsPayload';
import { CamelCaseWithReplacePipe } from '../../../../pipes/app.pipe';
@Component({
selector: 'rtl-boltz-swaps',
@ -35,6 +36,8 @@ export class BoltzSwapsComponent implements OnInit, AfterViewInit, OnChanges, On
@Input() emptyTableMessage = 'No swaps available.';
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'boltz';
public tableSettingSwapOut: TableSetting = { tableId: 'swap_out', recordsPerPage: PAGE_SIZE, sortBy: 'status', sortOrder: SortOrderEnum.DESCENDING };
@ -51,7 +54,7 @@ export class BoltzSwapsComponent implements OnInit, AfterViewInit, OnChanges, On
public screenSizeEnum = ScreenSizeEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private boltzService: BoltzService) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private boltzService: BoltzService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -111,6 +114,39 @@ export class BoltzSwapsComponent implements OnInit, AfterViewInit, OnChanges, On
}
}
getLabel(column: string) {
const tableId = (this.selectedSwapType === SwapTypeEnum.SWAP_IN) ? this.tableSettingSwapIn.tableId : this.tableSettingSwapOut.tableId;
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.listSwaps.filterPredicate = (swap: Swap, fltr: string) => JSON.stringify(swap).toLowerCase().includes(fltr);
// this.listSwaps.filterPredicate = (rowData: Swap, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
onSwapClick(selSwap: Swap | ReverseSwap, event: any) {
this.boltzService.swapInfo(selSwap.id || '').pipe(takeUntil(this.unSubs[1])).
subscribe((fetchedSwap: any) => {
@ -153,11 +189,11 @@ export class BoltzSwapsComponent implements OnInit, AfterViewInit, OnChanges, On
} else {
this.listSwaps.sort?.sort({ id: this.tableSettingSwapOut.sortBy, start: this.tableSettingSwapOut.sortOrder, disableClear: true });
}
this.listSwaps.filterPredicate = (swap: Swap, fltr: string) => JSON.stringify(swap).toLowerCase().includes(fltr);
if (this.paginator) {
this.paginator.firstPage();
}
this.listSwaps.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.listSwaps);
}

@ -4,9 +4,16 @@
<fa-icon [icon]="faHistory" class="page-title-img mr-1"></fa-icon>
<span class="page-title">{{swapCaption}} History</span>
</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start center" class="w-100">
<div [perfectScrollbar] class="table-container" fxFlex="100">
@ -46,7 +53,7 @@
<ng-container matColumnDef="htlc_address">
<th mat-header-cell *matHeaderCellDef mat-sort-header>HTLC Address</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.htlc_address}}</span>
</span>
</td>
@ -54,7 +61,7 @@
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.id}}</span>
</span>
</td>
@ -62,7 +69,7 @@
<ng-container matColumnDef="id_bytes">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID (Bytes)</th>
<td mat-cell *matCellDef="let swap">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}">
<span class="ellipsis-child">{{swap?.id_bytes}}</span>
</span>
</td>

@ -8,16 +8,17 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { LoopSwapStatus } from '../../../../models/loopModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, LoopTypeEnum, LoopStateEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS } from '../../../../services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, LoopTypeEnum, LoopStateEnum, SortOrderEnum, LND_DEFAULT_PAGE_SETTINGS, LND_PAGE_DEFS } from '../../../../services/consts-enums-functions';
import { LoggerService } from '../../../../services/logger.service';
import { CommonService } from '../../../../services/common.service';
import { LoopService } from '../../../../services/loop.service';
import { RTLState } from '../../../../../store/rtl.state';
import { openAlert } from '../../../../../store/rtl.actions';
import { PageSettings, TableSetting } from '../../../../models/pageSettings';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../../models/pageSettings';
import { lndPageSettings } from '../../../../../lnd/store/lnd.selector';
import { ApiCallStatusPayload } from '../../../../models/apiCallsPayload';
import { CamelCaseWithReplacePipe } from '../../../../pipes/app.pipe';
@Component({
selector: 'rtl-swaps',
@ -35,6 +36,8 @@ export class SwapsComponent implements OnInit, AfterViewInit, OnChanges, OnDestr
@Input() emptyTableMessage = 'No swaps available.';
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs = LND_PAGE_DEFS;
public selFilterBy = 'all';
public colWidth = '20rem';
public PAGE_ID = 'loop';
public tableSetting: TableSetting = { tableId: 'loop', recordsPerPage: PAGE_SIZE, sortBy: 'initiation_time', sortOrder: SortOrderEnum.DESCENDING };
@ -50,7 +53,7 @@ export class SwapsComponent implements OnInit, AfterViewInit, OnChanges, OnDestr
public screenSizeEnum = ScreenSizeEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private loopService: LoopService) {
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private loopService: LoopService, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
@ -88,6 +91,38 @@ export class SwapsComponent implements OnInit, AfterViewInit, OnChanges, OnDestr
this.listSwaps.filter = this.selFilter.trim().toLowerCase();
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.listSwaps.filterPredicate = (swap: LoopSwapStatus, fltr: string) => JSON.stringify(swap).toLowerCase().includes(fltr);
// this.listSwaps.filterPredicate = (rowData: LoopSwapStatus, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
onSwapClick(selSwap: LoopSwapStatus, event: any) {
this.loopService.getSwap(selSwap.id_bytes?.replace(/\//g, '_')?.replace(/\+/g, '-') || '').pipe(takeUntil(this.unSubs[1])).
subscribe((fetchedSwap: LoopSwapStatus) => {
@ -120,8 +155,8 @@ export class SwapsComponent implements OnInit, AfterViewInit, OnChanges, OnDestr
this.listSwaps.sort = this.sort;
this.listSwaps.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.listSwaps.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.listSwaps.filterPredicate = (swap: LoopSwapStatus, fltr: string) => JSON.stringify(swap).toLowerCase().includes(fltr);
this.listSwaps.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.listSwaps);
}

@ -2,9 +2,16 @@
<div fxLayout="column" fxLayoutAlign="start stretch">
<div fxLayout="column" fxLayoutAlign="start stretch" fxLayout.gt-sm="row wrap" class="page-sub-title-container mt-1">
<div fxFlex="70"></div>
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput [(ngModel)]="filterValue" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
<div fxFlex="30" fxLayoutAlign.gt-xs="space-between center" fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49">
<mat-select placeholder="Filter By" tabindex="1" [(ngModel)]="selFilterBy" (selectionChange)="selFilter=''; applyFilter()" name="filterBy">
<mat-option *ngFor="let column of ['all'].concat(displayedColumns.slice(0, -1))" [value]="column">{{getLabel(column)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="49">
<input matInput [(ngModel)]="selFilter" (input)="applyFilter()" (keyup)="applyFilter()" name="filter" placeholder="Filter">
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="start start">
<div [perfectScrollbar] fxLayout="column" class="table-container" fxFlex="100">

@ -1,16 +1,19 @@
import { Component, ViewChild, Input, AfterViewInit, OnChanges, SimpleChanges, OnInit } from '@angular/core';
import { Component, ViewChild, Input, AfterViewInit, OnChanges, SimpleChanges, OnInit, OnDestroy } from '@angular/core';
import { DatePipe } from '@angular/common';
import { Store } from '@ngrx/store';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, SCROLL_RANGES, SortOrderEnum } from '../../services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, SCROLL_RANGES, SortOrderEnum, LND_PAGE_DEFS, CLN_PAGE_DEFS, ECL_PAGE_DEFS } from '../../services/consts-enums-functions';
import { CommonService } from '../../services/common.service';
import { RTLState } from '../../../store/rtl.state';
import { openAlert } from '../../../store/rtl.actions';
import { TableSetting } from '../../models/pageSettings';
import { ColumnDefinition, TableSetting } from '../../models/pageSettings';
import { Subject, takeUntil } from 'rxjs';
import { rootSelectedNode } from '../../../store/rtl.selector';
import { CamelCaseWithReplacePipe } from '../../pipes/app.pipe';
@Component({
selector: 'rtl-transactions-report-table',
@ -20,15 +23,17 @@ import { TableSetting } from '../../models/pageSettings';
{ provide: MatPaginatorIntl, useValue: getPaginatorLabel('Transactions') }
]
})
export class TransactionsReportTableComponent implements OnInit, AfterViewInit, OnChanges {
export class TransactionsReportTableComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy {
@Input() dataRange = SCROLL_RANGES[0];
@Input() dataList = [];
@Input() filterValue = '';
@Input() selFilter = '';
@Input() displayedColumns: any[] = ['date', 'amount_paid', 'num_payments', 'amount_received', 'num_invoices'];
@Input() tableSetting: TableSetting = { tableId: 'transactions', recordsPerPage: PAGE_SIZE, sortBy: 'date', sortOrder: SortOrderEnum.DESCENDING };
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public nodePageDefs: any = LND_PAGE_DEFS;
public selFilterBy = 'all';
public timezoneOffset = new Date(Date.now()).getTimezoneOffset() * 60;
public scrollRanges = SCROLL_RANGES;
public transactions: any = new MatTableDataSource([]);
@ -36,12 +41,17 @@ export class TransactionsReportTableComponent implements OnInit, AfterViewInit,
public pageSizeOptions = PAGE_SIZE_OPTIONS;
public screenSize = '';
public screenSizeEnum = ScreenSizeEnum;
unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe) {
constructor(private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private camelCaseWithReplace: CamelCaseWithReplacePipe) {
this.screenSize = this.commonService.getScreenSize();
}
ngOnInit() {
this.store.select(rootSelectedNode).pipe(takeUntil(this.unSubs[0])).subscribe((selNode) => {
this.nodePageDefs = (selNode.lnImplementation === 'CLN') ? CLN_PAGE_DEFS : (selNode.lnImplementation === 'ECL') ? ECL_PAGE_DEFS : LND_PAGE_DEFS;
});
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
if (this.dataList && this.dataList.length > 0) {
this.loadTransactionsTable(this.dataList);
@ -57,7 +67,7 @@ export class TransactionsReportTableComponent implements OnInit, AfterViewInit,
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.loadTransactionsTable(this.dataList);
}
if (changes.filterValue && !changes.filterValue.firstChange) {
if (changes.selFilter && !changes.selFilter.firstChange) {
this.applyFilter();
}
}
@ -83,10 +93,45 @@ export class TransactionsReportTableComponent implements OnInit, AfterViewInit,
applyFilter() {
if (this.transactions) {
this.transactions.filter = this.filterValue.trim().toLowerCase();
this.transactions.filter = this.selFilter.trim().toLowerCase();
}
}
getLabel(column: string) {
const returnColumn: ColumnDefinition = this.nodePageDefs['reports'][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);
return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithReplace.transform(returnColumn.column, '_') : 'all';
}
setFilterPredicate() {
this.transactions.filterPredicate = (rowData: any, fltr: string) => {
const newRowData = ((rowData.date) ? (this.datePipe.transform(rowData.date, 'dd/MMM') + '/' + rowData.date.getFullYear()).toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
// this.transactions.filterPredicate = (rowData: LoopSwapStatus, fltr: string) => {
// let rowToFilter = '';
// switch (this.selFilterBy) {
// case 'all':
// for (let i = 0; i < this.displayedColumns.length - 1; i++) {
// rowToFilter = rowToFilter + (
// (this.displayedColumns[i] === '') ?
// (rowData ? rowData..toLowerCase() : '') :
// (rowData[this.displayedColumns[i]] ? rowData[this.displayedColumns[i]].toLowerCase() : '')
// ) + ', ';
// }
// break;
// case '':
// rowToFilter = (rowData ? rowData..toLowerCase() : '');
// break;
// default:
// rowToFilter = (rowData[this.selFilterBy] ? rowData[this.selFilterBy].toLowerCase() : '');
// break;
// }
// return rowToFilter.includes(fltr);
// };
}
loadTransactionsTable(trans: any[]) {
this.transactions = trans ? new MatTableDataSource([...trans]) : new MatTableDataSource([]);
this.setTableWidgets();
@ -97,11 +142,9 @@ export class TransactionsReportTableComponent implements OnInit, AfterViewInit,
this.transactions.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.transactions.sort = this.sort;
this.transactions.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.transactions.filterPredicate = (rowData: any, fltr: string) => {
const newRowData = ((rowData.date) ? (this.datePipe.transform(rowData.date, 'dd/MMM') + '/' + rowData.date.getFullYear()).toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr);
};
this.transactions.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
}
}
@ -111,4 +154,11 @@ export class TransactionsReportTableComponent implements OnInit, AfterViewInit,
}
}
ngOnDestroy(): void {
this.unSubs.forEach((unsub) => {
unsub.next();
unsub.complete();
});
}
}

Loading…
Cancel
Save