You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RTL/frontend/src_app_eclair_ecl_module_t...

1 line
539 KiB
Plaintext

{"version":3,"file":"src_app_eclair_ecl_module_ts.2266e5b7139d698d.js","mappings":"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","names":["i0","ECLRootComponent","constructor","router","this","events","subscribe","event","NavigationStart","loading","NavigationEnd","NavigationCancel","NavigationError","static","core","selectors","routeAnimation","ECLNodeInfoComponent","commonService","ngOnChanges","chains","push","information","network","titleCase","ECLBalancesInfoComponent","onchain","lightning","total","ECLFeeInfoComponent","name","value","fees","monthly_fee","totalFees","weekly_fee","daily_fee","m","Math","ceil","log","LN10","maxFeeValue","Object","assign","ECLChannelStatusInfoComponent","ECLChannelCapacityInfoComponent","faBalanceScale","faDumbbell","goToChannels","navigateByUrl","ECLChannelLiquidityInfoComponent","ScreenSizeEnum","ngOnInit","screenSize","getScreenSize","ECLLightningSendPaymentsComponent","dialogRef","store","eclEffects","logger","decimalPipe","actions","dataService","faExclamationTriangle","FEE_LIMIT_TYPES","Subject","select","eclNodeSettings","pipe","takeUntil","unSubs","nodeSettings","selNode","allChannelsInfo","allChannelsSelector","activeChannels","info","filter","action","type","ECLActions","close","payload","status","APICallStatusEnum","paymentDecoded","amount","paymentError","message","onSendPayment","paymentRequest","timestamp","sendPayment","paymentAmount","paymentDecodedHint","paymentReq","control","setErrors","decodePayment","take","next","decodedPayment","zeroAmtInvoice","description","fiatConversion","convertCurrency","CurrencyUnitEnum","currencyUnits","length","data","transform","symbol","OTHER","CURRENCY_UNIT_FORMATS","error","err","JSON","stringify","decodeError","dispatch","invoice","amountMsat","fromDialog","onPaymentRequestEntry","trim","onAmountChange","resetData","selActiveChannel","feeLimit","selFeeLimitType","ngOnDestroy","forEach","completeSub","complete","ctx","ECLPaymentInformationComponent","payment","sentPaymentInfo","ngAfterViewChecked","shouldScroll","scrollContainer","nativeElement","classList","includes","onScrollDown","scrollTop","onExpansionOpen","opened","expansionOpen","onClose","MAT_DIALOG_DATA","ECLLightningPaymentsComponent","rtlEffects","datePipe","camelCaseWithSpaces","ECL_PAGE_DEFS","tableId","recordsPerPage","PAGE_SIZE","sortBy","sortOrder","SortOrderEnum","faHistory","MatTableDataSource","PAGE_SIZE_OPTIONS","eclNodeInformation","nodeInfo","eclPageSettings","settings","errorMessage","apiCallStatus","tableSetting","pageSettings","find","page","pageId","PAGE_ID","tables","table","ECL_DEFAULT_PAGE_SETTINGS","displayedColumns","parse","columnSelectionSM","columnSelection","partColumns","map","col","pageSize","colWidth","getContainerSize","width","payments","paymentsSeletor","paymentJSONArr","sent","sort","paginator","loadPaymentsTable","ngAfterViewInit","applyFilter","selFilter","toLowerCase","getLabel","column","returnColumn","nodePageDefs","allowedColumns","label","setFilterPredicate","filterPredicate","rowData","fltr","rowToFilter","selFilterBy","firstPartTimestamp","Date","toString","payms","sortingDataAccessor","sortHeaderId","sortByKey","parts","direction","id","recipientNodeAlias","recipientAmount","isNaN","toLocaleLowerCase","start","disableClear","newlyAddedPayment","paymentHash","reorderedPaymentDecoded","key","title","nodeId","DataTypeEnum","expiry","minFinalCltvExpiry","openConfirmation","AlertTypeEnum","alertTitle","noBtnText","yesBtnText","closeConfirm","confirmRes","titleMsg","flgShowInput","titleMessage","getInputs","placeholder","inputType","inputValue","openSendPaymentModal","openAlert","component","form","resetForm","is_group","index","onPaymentClick","selPayment","decodePayments","setTimeout","showPaymentView","onPartClick","selPart","showPartView","reorderedPart","paymentPreimage","toChannelId","feesPaid","splice","onDownloadCSV","paymentsDataCopy","paymentRequests","reduce","paymentReqs","decodedPayments","idx","flattenedPayments","acc","curr","concat","downloadFile","MatSort","MatPaginator","provide","MatPaginatorIntl","useValue","getPaginatorLabel","decls","ECLCreateInvoiceComponent","TimeUnitEnum","TIME_UNITS","invoiceError","onAddInvoice","expiryInSecs","selTimeUnit","convertTime","invoicePayload","invoiceValue","expireIn","createInvoice","private","invoiceValueHint","onInvoiceValueChange","unit","onTimeUnitChange","ECLLightningInvoicesComponent","unshift","invoices","invoicesSelector","invoiceJSONArr","loadInvoicesTable","resLookup","updateInvoicesData","openCreateInvoiceModal","newlyAddedInvoiceMemo","random","slice","now","newlyAddedInvoiceValue","onInvoiceClick","selInvoice","newlyAdded","ECLInvoiceInformationComponent","onRefreshInvoice","invoiceLookup","newInvoice","indexOf","invs","ECLHomeComponent","faSmile","faFrown","faAngleDoubleDown","faAngleDoubleUp","faChartPie","faBolt","faServer","faNetworkWired","UserPersonaEnum","localBalance","remoteBalance","balancedness","operatorCards","goToOptions","links","icon","cols","rows","merchantCards","nodeInfoStatus","selNodeInfoStatusSelector","errorMessages","apiCallStatusNodeInfo","feesSelector","apiCallStatusFees","withLatestFrom","onchainBalance","oCBalanceSelector","apiCallStatusAllChannels","apiCallStatusOCBal","channels","balances","lightningBalance","local","remote","channelBalances","abs","toFixed","channelsStatus","totalInboundLiquidity","totalOutboundLiquidity","allChannelsCapacity","sortDescByKey","allInboundChannels","channel","toRemote","allOutboundChannels","toLocal","floor","onNavigateTo","link","onsortChannelsBy","sortField","a","b","x","y","ECLOnChainSendModalComponent","ADDRESS_TYPES","CURRENCY_UNITS","rootSelectedNode","amountUnits","openSnackBar","sendFundError","onSendFunds","invalidValues","transaction","selAmountUnit","parseInt","sendOnchainFunds","amountError","address","blocks","onAmountUnitChange","self","prevSelectedUnit","currSelectedUnit","currencyUnitFormats","replace","ECLOnChainTransactionHistoryComponent","fetchTransactions","transactions","transactionsSelector","loadTransactionsTable","listTransactions","onTransactionClick","selTransaction","reorderedTransactions","blockHash","txid","confirmations","ECLOnChainComponent","faExchangeAlt","dataValue","linkFound","url","activeLink","e","ResolveEnd","urlAfterRedirects","confirmed","unconfirmed","openSendFundsModal","ECLConnectionsComponent","faUsers","findIndex","substring","lastIndexOf","peers","peersSelector","activePeers","active","onSelectedTabChange","ECLTransactionsComponent","tooltip","allChannels","userPersona","ECLRoutingComponent","faMapSigns","ECLNodeLookupComponent","snackBar","NodeFeaturesECL","addresses","lookupResult","onCopyNodeURI","open","ECLLookupsComponent","UntypedFormControl","faSearch","flgLoading","selectedFieldId","nodeLookupValue","nodeid","channelLookupValue","flgSetLookupValue","lookupKeyCtrl","valueChanges","onLookup","required","invalid","peerLookup","onSelectChange","setValue","clearLookupValue","ECLOnChainReceiveComponent","onGenerateAddress","getNewAddress","setNewAddress","newAddress","addressType","OnChainGeneratedAddressComponent","ECLOnChainSendComponent","activatedRoute","routeData","sweepAll","ECLOpenChannelComponent","totalBalance","balance","peer","isPrivate","unannouncedChannels","channelConnectionError","sortedPeers","p1","p2","alias","filteredPeers","selectedPeer","startWith","filterPeers","newlySelectedPeer","displayFn","onSelectedPeerChanged","selectedPubkey","selPeer","notfound","feeRate","fundingAmount","advancedTitle","onAdvancedPanelToggle","isClosed","onOpenChannel","saveChannelPayload","saveNewChannel","ECLChannelsTablesComponent","numOfOpenChannels","numOfPendingChannels","pending","numOfInactiveChannels","inactive","peerToAddChannelMessage","ECLChannelInformationComponent","faReceipt","channelsType","onShowAdvanced","showAdvanced","onCopyChanID","ECLChannelOpenTableComponent","faEye","faEyeSlash","FEE_RATE_TYPES","getCurrentNavigation","extras","state","loadChannelsTable","numPeers","ocBalSelector","onChannelUpdate","channelToUpdate","shortChannelId","channelId","feeBaseMsat","step","feeProportionalMillionths","min","hintFunction","percentHintFunction","base_fee","fee_rate","updateRequestPayload","isVersionCompatible","version","node_ids","baseFeeMsat","nodeIds","channel_ids","channelIds","updateChannel","onChannelClose","channelToClose","forceClose","closeChannel","force","onChannelClick","selChannel","announceChannel","ECLChannelPendingTableComponent","pendingChannels","ECLConnectPeerComponent","formBuilder","peerAddress","peerFormGroup","group","hiddenAddress","Validators","channelFormGroup","hiddenAmount","statusFormGroup","controls","flgEditable","newlyAddedPeer","stepper","peerConnectionError","onConnectPeer","saveNewPeer","stepSelectionChanged","selectedIndex","peerFormLabel","channelFormLabel","previouslySelectedIndex","ECLPeersComponent","peersData","loadPeersTable","availableBalance","setPeers","onPeerClick","reorderedPeer","showQRName","showQRField","peerToAddChannel","onPeerDetach","peerToDetach","disconnectPeer","ECLQueryRoutesComponent","faRoute","qrHops","setQueryRoutes","queryRoute","routes","allQRoutes","route","i","onQueryRoutes","getQueryRoutes","onHopClick","selHop","reorderedHop","ECLChannelInactiveTableComponent","inactiveChannels","ECLForwardingHistoryComponent","paymentsSelector","eventsData","relayed","loadForwardingEventsTable","changes","currentValue","firstChange","onForwardingEventClick","selFEvent","reorderedFHEvent","round","amountIn","amountOut","fromChannelAlias","fromShortChannelId","fromChannelId","toChannelAlias","toShortChannelId","camelCase","forwardingHistoryEvents","forwardingEvents","ECLRoutingPeersComponent","routingPeersData","sortIn","paginatorIn","sortOut","paginatorOut","loadRoutingPeersTable","applyFilterIncoming","routingPeersIncoming","filterIn","applyFilterOutgoing","routingPeersOutgoing","filterOut","rowDataIn","rowToFilterIn","selFilterByIn","rowDataOut","rowToFilterOut","selFilterByOut","results","groupRoutingPeers","incomingResults","outgoingResults","incoming","result","outgoing","totalAmount","totalFee","ECLReportsComponent","faChartBar","ECLRoutingReportComponent","SCROLL_RANGES","ReportBy","today","getFullYear","getMonth","getMonthDays","showYAxisLabel","filterForwardingEvents","startDate","endDate","containerSizeUpdated","CONTAINER_SIZE","screenPaddingX","view","height","end","startDateInSeconds","getTime","endDateInSeconds","toLocaleString","filteredEventsBySelectedPeriod","routingReportData","totalFeeSat","selReportBy","reportBy","EVENTS","prepareEventsReport","prepareFeeReport","onChartMouseUp","srcElement","tagName","eventFilterValue","onChartBarSelected","reportPeriod","padStart","MONTHS","feeReport","extra","totalEvents","monthNumber","dateNumber","secondsInADay","eventsReport","onSelectionChange","selectedValues","selMonth","selDate","selYear","selScrollRange","days","onSelReportByChange","yAxisLabel","fadeIn","ECLTransactionsReportComponent","paymentsSelectedPeriod","invoicesSelectedPeriod","amountPaidSelectedPeriod","amountReceivedSelectedPeriod","transactionsReportData","filterTransactionsForSelectedPeriod","transactionsNonZeroReportData","prepareTableData","transactionFilterValue","series","transactionsReport","transactionsReportSummary","filteredPayments","filteredInvoices","date","amountSettled","amount_paid","num_payments","amount_received","num_invoices","ECLGraphComponent","EclRoutes","path","children","pathMatch","redirectTo","canActivate","ECLUnlockedGuard","NotFoundComponent","ECLRouting","RouterModule","ECLModule","bootstrap","imports","CommonModule","SharedModule"],"sourceRoot":"webpack:///","sources":["./src/app/eclair/ecl-root.component.html","./src/app/eclair/ecl-root.component.ts","./src/app/eclair/home/node-info/node-info.component.html","./src/app/eclair/home/node-info/node-info.component.ts","./src/app/eclair/home/balances-info/balances-info.component.html","./src/app/eclair/home/balances-info/balances-info.component.ts","./src/app/eclair/home/fee-info/fee-info.component.html","./src/app/eclair/home/fee-info/fee-info.component.ts","./src/app/eclair/home/channel-status-info/channel-status-info.component.html","./src/app/eclair/home/channel-status-info/channel-status-info.component.ts","./src/app/eclair/home/channel-capacity-info/channel-capacity-info.component.html","./src/app/eclair/home/channel-capacity-info/channel-capacity-info.component.ts","./src/app/eclair/home/channel-liquidity-info/channel-liquidity-info.component.html","./src/app/eclair/home/channel-liquidity-info/channel-liquidity-info.component.ts","./src/app/eclair/transactions/send-payment-modal/send-payment.component.html","./src/app/eclair/transactions/send-payment-modal/send-payment.component.ts","./src/app/eclair/transactions/payment-information-modal/payment-information.component.html","./src/app/eclair/transactions/payment-information-modal/payment-information.component.ts","./src/app/eclair/transactions/payments/lightning-payments.component.html","./src/app/eclair/transactions/payments/lightning-payments.component.ts","./src/app/eclair/transactions/create-invoice-modal/create-invoice.component.html","./src/app/eclair/transactions/create-invoice-modal/create-invoice.component.ts","./src/app/eclair/transactions/invoices/lightning-invoices.component.html","./src/app/eclair/transactions/invoices/lightning-invoices.component.ts","./src/app/eclair/home/home.component.html","./src/app/eclair/home/home.component.ts","./src/app/eclair/on-chain/on-chain-send-modal/on-chain-send-modal.component.html","./src/app/eclair/on-chain/on-chain-send-modal/on-chain-send-modal.component.ts","./src/app/eclair/on-chain/on-chain-transaction-history/on-chain-transaction-history.component.html","./src/app/eclair/on-chain/on-chain-transaction-history/on-chain-transaction-history.component.ts","./src/app/eclair/on-chain/on-chain.component.html","./src/app/eclair/on-chain/on-chain.component.ts","./src/app/eclair/peers-channels/connections.component.html","./src/app/eclair/peers-channels/connections.component.ts","./src/app/eclair/transactions/transactions.component.html","./src/app/eclair/transactions/transactions.component.ts","./src/app/eclair/routing/routing.component.html","./src/app/eclair/routing/routing.component.ts","./src/app/eclair/graph/lookups/node-lookup/node-lookup.component.html","./src/app/eclair/graph/lookups/node-lookup/node-lookup.component.ts","./src/app/eclair/graph/lookups/lookups.component.html","./src/app/eclair/graph/lookups/lookups.component.ts","./src/app/eclair/on-chain/on-chain-receive/on-chain-receive.component.ts","./src/app/eclair/on-chain/on-chain-receive/on-chain-receive.component.html","./src/app/eclair/on-chain/on-chain-send/on-chain-send.component.ts","./src/app/eclair/on-chain/on-chain-send/on-chain-send.component.html","./src/app/eclair/peers-channels/channels/open-channel-modal/open-channel.component.html","./src/app/eclair/peers-channels/channels/open-channel-modal/open-channel.component.ts","./src/app/eclair/peers-channels/channels/channels-tables/channels-tables.component.html","./src/app/eclair/peers-channels/channels/channels-tables/channels-tables.component.ts","./src/app/eclair/peers-channels/channels/channel-information-modal/channel-information.component.html","./src/app/eclair/peers-channels/channels/channel-information-modal/channel-information.component.ts","./src/app/eclair/peers-channels/channels/channels-tables/channel-open-table/channel-open-table.component.html","./src/app/eclair/peers-channels/channels/channels-tables/channel-open-table/channel-open-table.component.ts","./src/app/eclair/peers-channels/channels/channels-tables/channel-pending-table/channel-pending-table.component.html","./src/app/eclair/peers-channels/channels/channels-tables/channel-pending-table/channel-pending-table.component.ts","./src/app/eclair/peers-channels/connect-peer/connect-peer.component.html","./src/app/eclair/peers-channels/connect-peer/connect-peer.component.ts","./src/app/eclair/peers-channels/peers/peers.component.html","./src/app/eclair/peers-channels/peers/peers.component.ts","./src/app/eclair/graph/query-routes/query-routes.component.html","./src/app/eclair/graph/query-routes/query-routes.component.ts","./src/app/eclair/peers-channels/channels/channels-tables/channel-inactive-table/channel-inactive-table.component.html","./src/app/eclair/peers-channels/channels/channels-tables/channel-inactive-table/channel-inactive-table.component.ts","./src/app/eclair/routing/forwarding-history/forwarding-history.component.html","./src/app/eclair/routing/forwarding-history/forwarding-history.component.ts","./src/app/eclair/routing/routing-peers/routing-peers.component.html","./src/app/eclair/routing/routing-peers/routing-peers.component.ts","./src/app/eclair/reports/reports.component.html","./src/app/eclair/reports/reports.component.ts","./src/app/eclair/reports/routing/routing-report.component.html","./src/app/eclair/reports/routing/routing-report.component.ts","./src/app/eclair/reports/transactions/transactions-report.component.html","./src/app/eclair/reports/transactions/transactions-report.component.ts","./src/app/eclair/graph/graph.component.html","./src/app/eclair/graph/graph.component.ts","./src/app/eclair/ecl.routing.ts","./src/app/eclair/ecl.module.ts"],"sourcesContent":["<div class=\"inner-sidenav-content\" fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start stretch\">\n <mat-progress-bar *ngIf=\"loading\" color=\"primary\" mode=\"indeterminate\"></mat-progress-bar>\n <router-outlet #outlet=\"outlet\"></router-outlet>\n</div>\n","import { Component } from '@angular/core';\nimport { Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';\nimport { routeAnimation } from '../shared/animation/route-animation';\n\n@Component({\n selector: 'rtl-ecl-root',\n templateUrl: './ecl-root.component.html',\n styleUrls: ['./ecl-root.component.scss'],\n animations: [routeAnimation]\n})\nexport class ECLRootComponent {\n\n loading = false;\n\n constructor(private router: Router) {\n this.router.events.subscribe((event: Event) => {\n switch (true) {\n case event instanceof NavigationStart: {\n this.loading = true;\n break;\n }\n case event instanceof NavigationEnd:\n case event instanceof NavigationCancel:\n case event instanceof NavigationError: {\n this.loading = false;\n break;\n }\n default: {\n break;\n }\n }\n });\n }\n\n}\n","<div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <div>\n <h4 class=\"dashboard-info-title\">Alias</h4>\n <div class=\"overflow-wrap dashboard-info-value\">\n {{information?.alias}}\n <span *ngIf=\"!showColorFieldSeparately\" class=\"dashboard-node-dot dot\" [ngStyle]=\"{'backgroundColor': information?.color}\"></span>\n </div>\n </div>\n <div *ngIf=\"showColorFieldSeparately\">\n <h4 class=\"dashboard-info-title\">Color</h4>\n <div class=\"overflow-wrap dashboard-info-value\">\n <span class=\"dashboard-node-square\" [ngStyle]=\"{'backgroundColor': information?.color}\"></span>\n {{information?.color | uppercase}}\n </div>\n </div>\n <div>\n <h4 class=\"dashboard-info-title\">Implementation</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{(information?.lnImplementation || information?.version) ? information?.lnImplementation + ' ' + information?.version : ''}}</div>\n </div>\n <div>\n <h4 class=\"dashboard-info-title\">Chain</h4>\n <span *ngFor=\"let chain of chains\" class=\"overflow-wrap dashboard-info-value\">{{chain}}</span>\n </div>\n</div>\n","import { Component, OnChanges, Input } from '@angular/core';\nimport { GetInfo } from '../../../shared/models/eclModels';\nimport { CommonService } from '../../../shared/services/common.service';\n\n@Component({\n selector: 'rtl-ecl-node-info',\n templateUrl: './node-info.component.html',\n styleUrls: ['./node-info.component.scss']\n})\nexport class ECLNodeInfoComponent implements OnChanges {\n\n @Input() information: GetInfo;\n @Input() showColorFieldSeparately: boolean;\n public chains: Array<string> = [''];\n\n constructor(private commonService: CommonService) { }\n\n ngOnChanges() {\n this.chains = [];\n this.chains.push('Bitcoin ' + (this.information.network ? this.commonService.titleCase(this.information.network) : 'Testnet'));\n }\n\n}\n","<div *ngIf=\"errorMessage?.trim() === ''; else errorBlock\" fxLayout=\"column\" fxFlex=\"100\"fxLayoutAlign=\"space-between stretch\">\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Lightning</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{balances.lightning | number}} Sats</div>\n <mat-progress-bar class=\"dashboard-progress-bar\" mode=\"determinate\" value=\"{{balances.lightning/balances.total*100}}\"></mat-progress-bar>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">On-chain</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{balances.onchain | number}} Sats</div>\n <mat-progress-bar class=\"dashboard-progress-bar\" mode=\"determinate\" value=\"{{balances.onchain/balances.total*100}}\"></mat-progress-bar>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Total</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{balances.total | number}} Sats</div>\n </div>\n</div>\n<ng-template #errorBlock>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between\" class=\"p-2\">\n <p>{{errorMessage}}</p>\n </div>\n</ng-template>\n","import { Component, Input } from '@angular/core';\n\n@Component({\n selector: 'rtl-ecl-balances-info',\n templateUrl: './balances-info.component.html',\n styleUrls: ['./balances-info.component.scss']\n})\nexport class ECLBalancesInfoComponent {\n\n @Input() balances = { onchain: 0, lightning: 0, total: 0 };\n @Input() errorMessage: string;\n\n constructor() {}\n\n}\n","<div *ngIf=\"errorMessage?.trim() === ''; else errorBlock\" fxLayout=\"row\" fxFlex=\"100\"fxLayoutAlign=\"start stretch\">\n <div fxLayout=\"column\" fxFlex=\"50\" fxLayoutAlign=\"space-between stretch\">\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Daily</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{fees?.daily_fee | number}} Sats</div>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Weekly</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{fees?.weekly_fee | number}} Sats</div>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Monthly</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{fees?.monthly_fee | number}} Sats</div>\n </div>\n </div>\n <div fxLayout=\"column\" fxFlex=\"50\" fxLayoutAlign=\"space-between stretch\">\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Transactions</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{fees?.daily_txs | number}}</div>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Transactions</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{fees?.weekly_txs | number}}</div>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Transactions</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{fees?.monthly_txs | number}}</div>\n </div>\n </div>\n</div>\n<ng-template #errorBlock>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between\" class=\"p-2\">\n <p>{{errorMessage}}</p>\n </div>\n</ng-template>\n","import { Component, OnChanges, Input } from '@angular/core';\nimport { Fees } from '../../../shared/models/eclModels';\n\n@Component({\n selector: 'rtl-ecl-fee-info',\n templateUrl: './fee-info.component.html',\n styleUrls: ['./fee-info.component.scss']\n})\nexport class ECLFeeInfoComponent implements OnChanges {\n\n @Input() fees: Fees;\n @Input() errorMessage: string;\n totalFees = [{ name: 'Monthly', value: 0 }, { name: 'Weekly', value: 0 }, { name: 'Daily', value: 0 }];\n maxFeeValue = 100;\n\n constructor() { }\n\n ngOnChanges() {\n if (this.fees?.monthly_fee) {\n this.totalFees = [{ name: 'Monthly', value: this.fees.monthly_fee }, { name: 'Weekly', value: this.fees.weekly_fee || 0 }, { name: 'Daily ', value: this.fees.daily_fee || 0 }];\n const e = Math.ceil(Math.log(this.fees.monthly_fee + 1) / Math.LN10);\n const m = 10 ** (e - 1);\n this.maxFeeValue = (Math.ceil(this.fees.monthly_fee / m) * m) / 5 || 100;\n Object.assign(this, this.totalFees);\n } else {\n this.totalFees = [{ name: 'Monthly', value: 0 }, { name: 'Weekly', value: 0 }, { name: 'Daily', value: 0 }];\n this.maxFeeValue = 100;\n Object.assign(this, this.totalFees);\n }\n }\n\n}\n","<div *ngIf=\"errorMessage?.trim() === ''; else errorBlock\" fxLayout=\"row\" fxFlex=\"100\"fxLayoutAlign=\"start stretch\">\n <div fxLayout=\"column\" fxFlex=\"50\" fxLayoutAlign=\"space-between stretch\">\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Active</h4>\n <div class=\"overflow-wrap dashboard-info-value\"><span class=\"dot tiny-dot green\"></span>{{(channelsStatus.active?.channels || 0) | number}}</div>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Pending</h4>\n <div class=\"overflow-wrap dashboard-info-value\"><span class=\"dot tiny-dot yellow\"></span>{{(channelsStatus.pending?.channels || 0) | number}}</div>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Inactive</h4>\n <div class=\"overflow-wrap dashboard-info-value\"><span class=\"dot tiny-dot grey\"></span>{{(channelsStatus.inactive?.channels || 0) | number}}</div>\n </div>\n </div>\n <div fxLayout=\"column\" fxFlex=\"50\" fxLayoutAlign=\"space-between stretch\">\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Capacity</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{(channelsStatus.active?.capacity || 0) | number}} Sats</div>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Capacity</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{(channelsStatus.pending?.capacity || 0) | number}} Sats</div>\n </div>\n <div>\n <h4 fxLayoutAlign=\"start\" class=\"dashboard-info-title\">Capacity</h4>\n <div class=\"overflow-wrap dashboard-info-value\">{{(channelsStatus.inactive?.capacity || 0) | number}} Sats</div>\n </div>\n </div>\n</div>\n<ng-template #errorBlock>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between\" class=\"p-2\">\n <p>{{errorMessage}}</p>\n </div>\n</ng-template>\n","import { Component, Input } from '@angular/core';\nimport { ChannelsStatus } from '../../../shared/models/eclModels';\n\n@Component({\n selector: 'rtl-ecl-channel-status-info',\n templateUrl: './channel-status-info.component.html',\n styleUrls: ['./channel-status-info.component.scss']\n})\nexport class ECLChannelStatusInfoComponent {\n\n @Input() channelsStatus: ChannelsStatus = {};\n @Input() errorMessage: string;\n\n constructor() {}\n\n}\n","<div *ngIf=\"errorMessage?.trim() === ''; else errorBlock\" fxLayout=\"column\" fxLayoutAlign=\"space-between stretch\"fxFlex=\"100\">\n <div fxLayout=\"column\" fxFlex=\"9\" fxLayoutAlign=\"end start\">\n <span class=\"dashboard-capacity-header this-channel-capacity\">Total Capacity</span>\n <div fxLayout=\"row\" fxLayoutAlign=\"space-between start\" class=\"w-100\">\n <mat-hint fxFlex=\"40\" fxLayoutAlign=\"start center\" class=\"font-size-90\"><strong class=\"font-weight-900 mr-5px\">Local:</strong>{{channelBalances?.localBalance || 0 | number:'1.0-0'}} Sats</mat-hint>\n <mat-hint fxFlex=\"20\" fxLayoutAlign=\"center center\" class=\"font-size-90\">\n <fa-icon class=\"mr-3px\" matTooltip=\"Balance Score\" [icon]=\"faBalanceScale\"></fa-icon>\n ({{channelBalances?.balancedness || 0 | number}})\n </mat-hint>\n <mat-hint fxFlex=\"40\" fxLayoutAlign=\"end center\" class=\"font-size-90\"><strong class=\"font-weight-900 mr-5px\">Remote:</strong>{{channelBalances?.remoteBalance || 0 | number:'1.0-0'}} Sats</mat-hint>\n </div>\n <mat-progress-bar class=\"dashboard-progress-bar this-channel-bar\" mode=\"determinate\" color=\"accent\" value=\"{{channelBalances?.localBalance && channelBalances?.localBalance > 0 ? ((+channelBalances?.localBalance/((+channelBalances?.localBalance)+(+channelBalances?.remoteBalance)))*100) : 0}}\"></mat-progress-bar>\n </div>\n <div fxLayout=\"column\" fxFlex=\"3\" fxLayoutAlign=\"end stretch\"><mat-divider class=\"dashboard-divider\"></mat-divider></div>\n <div class=\"channels-capacity-scroll\" [perfectScrollbar]>\n <div *ngIf=\"allChannels && allChannels?.length > 0; else noChannelBlock\" fxLayout=\"column\"fxFlex=\"100\">\n <div *ngFor=\"let channel of allChannels\" class=\"mt-2\">\n <a class=\"dashboard-capacity-header\" [routerLink]=\"['../connections/channels/open']\" [state]=\"{filter: channel.channelId}\" matTooltip=\"{{channel.alias || channel.shortChannelId}}\" matTooltipDisabled=\"{{(channel.alias || channel.shortChannelId).length < 26}}\">\n {{(channel?.alias || channel?.shortChannelId) | slice:0:24}}{{(channel?.alias || channel?.shortChannelId).length > 25 ? '...' : ''}}\n </a>\n <div fxLayout=\"row\" fxLayoutAlign=\"space-between start\" class=\"w-100\">\n <mat-hint fxFlex=\"40\" fxLayoutAlign=\"start center\" class=\"font-size-90 color-primary\"><strong class=\"font-weight-900 mr-5px\">Local:</strong>{{channel?.toLocal || 0 | number:'1.0-0'}} Sats</mat-hint>\n <mat-hint fxFlex=\"20\" fxLayoutAlign=\"center center\" class=\"font-size-90 color-primary\">\n <fa-icon class=\"color-primary mr-3px\" matTooltip=\"Balance Score\" [icon]=\"faBalanceScale\"></fa-icon>\n ({{channel?.balancedness || 0 | number}})\n </mat-hint>\n <mat-hint fxFlex=\"40\" fxLayoutAlign=\"end center\" class=\"font-size-90 color-primary\"><strong class=\"font-weight-900 mr-5px\">Remote:</strong>{{channel?.toRemote || 0 | number:'1.0-0'}} Sats</mat-hint>\n </div>\n <mat-progress-bar class=\"dashboard-progress-bar\" mode=\"determinate\" value=\"{{channel.toLocal && channel.toLocal > 0 ? ((+channel.toLocal/((+channel.toLocal)+(+channel.toRemote)))*100) : 0}}\"></mat-progress-bar>\n </div>\n </div>\n </div>\n</div>\n<ng-template #noChannelBlock>\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between start\" class=\"mt-1 w-100\">\n No channels available.\n <button mat-stroked-button color=\"primary\" tabindex=\"1\" (click)=\"goToChannels()\">Open Channel</button>\n </div>\n</ng-template>\n<ng-template #errorBlock>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between\" class=\"p-2\">\n <p>{{errorMessage}}</p>\n </div>\n</ng-template>\n","import { Component, Input } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { faBalanceScale, faDumbbell } from '@fortawesome/free-solid-svg-icons';\n\nimport { Channel } from '../../../shared/models/eclModels';\n\n@Component({\n selector: 'rtl-ecl-channel-capacity-info',\n templateUrl: './channel-capacity-info.component.html',\n styleUrls: ['./channel-capacity-info.component.scss']\n})\nexport class ECLChannelCapacityInfoComponent {\n\n public faBalanceScale = faBalanceScale;\n public faDumbbell = faDumbbell;\n @Input() channelBalances: {localBalance: number, remoteBalance: number, balancedness: number};\n @Input() allChannels: Channel[];\n @Input() sortBy = 'Balance Score';\n @Input() errorMessage: string;\n\n constructor(private router: Router) {}\n\n goToChannels() {\n this.router.navigateByUrl('/ecl/connections');\n }\n\n}\n","<div *ngIf=\"errorMessage?.trim() === ''; else errorBlock\" fxLayout=\"column\" fxLayoutAlign=\"space-between stretch\" fxFlex=\"100\" [ngClass]=\"{'mb-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM, 'mb-2': screenSize === screenSizeEnum.MD, 'mb-1': screenSize === screenSizeEnum.LG || screenSize === screenSizeEnum.XL}\">\n <div fxLayout=\"column\" fxFlex=\"9\" fxLayoutAlign=\"end start\">\n <span class=\"dashboard-capacity-header this-channel-capacity\">Total Capacity</span>\n <mat-hint class=\"font-size-90\">{{totalLiquidity | number:'1.0-0'}} Sats</mat-hint>\n <mat-progress-bar class=\"dashboard-progress-bar this-channel-bar\" mode=\"determinate\" color=\"accent\" value=\"100\"></mat-progress-bar>\n </div>\n <div fxLayout=\"column\" fxFlex=\"3\" fxLayoutAlign=\"end stretch\"><mat-divider class=\"dashboard-divider\"></mat-divider></div>\n <div fxLayout=\"column\" fxFlex.gt-sm=\"88\" fxFlex=\"84\" fxLayoutAlign=\"start start\" [perfectScrollbar]>\n <div *ngIf=\"allChannels && allChannels.length > 0; else noChannelBlock\" fxLayout=\"column\" fxFlex=\"100\"class=\"w-100\">\n <div *ngFor=\"let channel of allChannels\" class=\"mt-2\">\n <a class=\"dashboard-capacity-header\" [routerLink]=\"['../connections/channels/open']\" [state]=\"{filter: channel.channelId}\" matTooltip=\"{{channel.alias || channel.shortChannelId}}\" matTooltipDisabled=\"{{(channel.alias || channel.shortChannelId).length < 26}}\">\n {{(channel.alias || channel.shortChannelId) | slice:0:24}}{{(channel.alias || channel.shortChannelId).length > 25 ? '...' : ''}}\n </a>\n <div fxLayout=\"row\" fxLayoutAlign=\"space-between start\" class=\"w-100\">\n <mat-hint *ngIf=\"direction === 'In'\" fxFlex=\"100\" fxLayoutAlign=\"start center\" class=\"font-size-90 color-primary\"><strong class=\"font-weight-900 mr-5px\">Capacity: </strong>{{channel.toRemote || 0 | number:'1.0-0'}} Sats</mat-hint>\n <mat-hint *ngIf=\"direction === 'Out'\" fxFlex=\"100\" fxLayoutAlign=\"start center\" class=\"font-size-90 color-primary\"><strong class=\"font-weight-900 mr-5px\">Capacity: </strong>{{channel.toLocal || 0 | number:'1.0-0'}} Sats</mat-hint>\n </div>\n <mat-progress-bar *ngIf=\"direction === 'In'\" class=\"dashboard-progress-bar\" mode=\"determinate\" value=\"{{(totalLiquidity > 0) ? ((+channel.toRemote || 0)/(totalLiquidity) * 100) : 0}}\"></mat-progress-bar>\n <mat-progress-bar *ngIf=\"direction === 'Out'\" class=\"dashboard-progress-bar\" mode=\"determinate\" value=\"{{(totalLiquidity > 0) ? ((+channel.toLocal || 0)/(totalLiquidity) * 100) : 0}}\"></mat-progress-bar>\n </div>\n </div>\n </div>\n</div>\n<ng-template #noChannelBlock>\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between start\" class=\"mt-1\">\n No channels available.\n <button *ngIf=\"direction === 'Out'\" mat-stroked-button color=\"primary\" tabindex=\"1\" (click)=\"goToChannels()\">Open Channel</button>\n </div>\n</ng-template>\n<ng-template #errorBlock>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between\" class=\"p-2\">\n <p>{{errorMessage}}</p>\n </div>\n</ng-template>\n","import { Component, Input, OnInit } from '@angular/core';\nimport { Router } from '@angular/router';\n\nimport { Channel } from '../../../shared/models/eclModels';\nimport { ScreenSizeEnum } from '../../../shared/services/consts-enums-functions';\nimport { CommonService } from '../../../shared/services/common.service';\n\n@Component({\n selector: 'rtl-ecl-channel-liquidity-info',\n templateUrl: './channel-liquidity-info.component.html',\n styleUrls: ['./channel-liquidity-info.component.scss']\n})\nexport class ECLChannelLiquidityInfoComponent implements OnInit {\n\n @Input() direction: string;\n @Input() totalLiquidity: number;\n @Input() allChannels: Channel[];\n @Input() errorMessage: string;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n\n constructor(private router: Router, private commonService: CommonService) {}\n\n ngOnInit() {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n goToChannels() {\n this.router.navigateByUrl('/ecl/connections');\n }\n\n}\n","<div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <mat-card-header fxLayout=\"row\" fxLayoutAlign=\"space-between center\" class=\"modal-info-header\">\n <div fxFlex=\"95\" fxLayoutAlign=\"start start\">\n <span class=\"page-title\">Send Payment</span>\n </div>\n <button tabindex=\"8\" fxFlex=\"5\" fxLayoutAlign=\"center\" class=\"btn-close-x p-0\" default mat-button [mat-dialog-close]=\"false\">X</button>\n </mat-card-header>\n <mat-card-content class=\"padding-gap-x-large\">\n <form #sendPaymentForm=\"ngForm\" fxLayoutAlign=\"space-between stretch\" fxLayout=\"column\">\n <mat-form-field fxFlex=\"100\">\n <textarea #paymentReq=\"ngModel\" autoFocus matInput placeholder=\"Payment Request\" name=\"paymentRequest\" rows=\"4\" tabindex=\"1\" required [ngModel]=\"paymentRequest\" (ngModelChange)=\"onPaymentRequestEntry($event)\" (matTextareaAutosize)=\"true\"></textarea>\n <mat-hint *ngIf=\"paymentRequest && paymentDecodedHint !== ''\">{{paymentDecodedHint}}</mat-hint>\n <mat-error *ngIf=\"!paymentRequest\">Payment request is required.</mat-error>\n <mat-error *ngIf=\"paymentReq.errors?.decodeError\">{{paymentDecodedHint}}</mat-error>\n </mat-form-field>\n <mat-form-field *ngIf=\"zeroAmtInvoice\" fxFlex=\"100\">\n <input #paymentAmt=\"ngModel\" matInput placeholder=\"Amount (Sats)\" name=\"amount\" tabindex=\"2\" required [(ngModel)]=\"paymentAmount\" (change)=\"onAmountChange($event)\">\n <mat-hint>It is a zero amount invoice, enter amount to be paid.</mat-hint>\n <mat-error *ngIf=\"!paymentAmount\">Payment amount is required.</mat-error>\n </mat-form-field>\n <div *ngIf=\"paymentError !== ''\" fxFlex=\"100\" class=\"alert alert-danger mt-1\">\n <fa-icon class=\"mr-1 alert-icon\" [icon]=\"faExclamationTriangle\"></fa-icon>\n <span *ngIf=\"paymentError !== ''\">{{paymentError}}</span>\n </div>\n <div class=\"mt-2\" fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button class=\"mr-1\" mat-button color=\"primary\" tabindex=\"2\" type=\"reset\" (click)=\"resetData()\">Clear Fields</button>\n <button mat-button color=\"primary\" tabindex=\"3\" (click)=\"onSendPayment();\">Send Payment</button>\n </div>\n </form>\n </mat-card-content>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';\nimport { NgModel } from '@angular/forms';\nimport { DecimalPipe } from '@angular/common';\nimport { Subject } from 'rxjs';\nimport { take, takeUntil, filter } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { Actions } from '@ngrx/effects';\nimport { MatDialogRef } from '@angular/material/dialog';\nimport { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';\n\nimport { SelNodeChild } from '../../../shared/models/RTLconfig';\nimport { PayRequest, Channel, LightningBalance, ChannelsStatus } from '../../../shared/models/eclModels';\nimport { APICallStatusEnum, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, ECLActions, FEE_LIMIT_TYPES } from '../../../shared/services/consts-enums-functions';\nimport { CommonService } from '../../../shared/services/common.service';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { DataService } from '../../../shared/services/data.service';\n\nimport { ECLEffects } from '../../store/ecl.effects';\nimport { RTLState } from '../../../store/rtl.state';\nimport { sendPayment } from '../../store/ecl.actions';\nimport { allChannelsInfo, eclNodeSettings } from '../../store/ecl.selector';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\n\n@Component({\n selector: 'rtl-ecl-lightning-send-payments',\n templateUrl: './send-payment.component.html',\n styleUrls: ['./send-payment.component.scss']\n})\nexport class ECLLightningSendPaymentsComponent implements OnInit, OnDestroy {\n\n @ViewChild('paymentReq', { static: false }) paymentReq: NgModel;\n public faExclamationTriangle = faExclamationTriangle;\n public selNode: SelNodeChild | null = {};\n public paymentDecoded: PayRequest = {};\n public zeroAmtInvoice = false;\n public paymentAmount = null;\n public paymentRequest = '';\n public paymentDecodedHint = '';\n public selActiveChannel: Channel | null = {};\n public activeChannels = {};\n public feeLimit = null;\n public selFeeLimitType = FEE_LIMIT_TYPES[0];\n public feeLimitTypes = FEE_LIMIT_TYPES;\n public paymentError = '';\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(public dialogRef: MatDialogRef<ECLLightningSendPaymentsComponent>, private store: Store<RTLState>, private eclEffects: ECLEffects, private logger: LoggerService, private commonService: CommonService, private decimalPipe: DecimalPipe, private actions: Actions, private dataService: DataService) { }\n\n ngOnInit() {\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((nodeSettings: SelNodeChild | null) => {\n this.selNode = nodeSettings;\n });\n this.store.select(allChannelsInfo).pipe(takeUntil(this.unSubs[1])).\n subscribe((allChannelsSelector: ({ activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], lightningBalance: LightningBalance, channelsStatus: ChannelsStatus, apiCallStatus: ApiCallStatusPayload })) => {\n this.activeChannels = allChannelsSelector.activeChannels;\n this.logger.info(allChannelsSelector);\n });\n this.actions.pipe(\n takeUntil(this.unSubs[1]),\n filter((action) => action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL || action.type === ECLActions.SEND_PAYMENT_STATUS_ECL)).\n subscribe((action: any) => {\n if (action.type === ECLActions.SEND_PAYMENT_STATUS_ECL) {\n this.dialogRef.close();\n }\n if (action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL && action.payload.status === APICallStatusEnum.ERROR && action.payload.action === 'SendPayment') {\n delete this.paymentDecoded.amount;\n this.paymentError = action.payload.message;\n }\n });\n }\n\n onSendPayment(): boolean | void {\n if (!this.paymentRequest) {\n return true;\n }\n if (this.paymentDecoded.timestamp) {\n this.sendPayment();\n } else {\n this.paymentAmount = null;\n this.paymentError = '';\n this.paymentDecodedHint = '';\n this.paymentReq.control.setErrors(null);\n this.dataService.decodePayment(this.paymentRequest, true).\n pipe(take(1)).subscribe({\n next: (decodedPayment: PayRequest) => {\n this.paymentDecoded = decodedPayment;\n if (this.paymentDecoded.timestamp && !this.paymentDecoded.amount) {\n this.paymentDecoded.amount = 0;\n this.zeroAmtInvoice = true;\n this.paymentDecodedHint = 'Zero Amount Invoice | Memo: ' + this.paymentDecoded.description;\n } else {\n this.zeroAmtInvoice = false;\n if (this.selNode && this.selNode.fiatConversion && this.paymentDecoded.amount) {\n this.commonService.convertCurrency(+this.paymentDecoded.amount, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).\n pipe(takeUntil(this.unSubs[2])).\n subscribe({\n next: (data) => {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount : 0) + ' Sats (' + data.symbol + this.decimalPipe.transform((data.OTHER ? data.OTHER : 0), CURRENCY_UNIT_FORMATS.OTHER) + ') | Memo: ' + this.paymentDecoded.description;\n }, error: (error) => {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount / 1000 : 0) + ' Sats | Memo: ' + this.paymentDecoded.description + '. Unable to convert currency.';\n }\n });\n } else {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount : 0) + ' Sats | Memo: ' + this.paymentDecoded.description;\n }\n }\n }, error: (err) => {\n this.logger.error(err);\n this.paymentDecodedHint = 'ERROR: ' + ((err.message) ? err.message : ((typeof err === 'string') ? err : JSON.stringify(err)));\n this.paymentReq.control.setErrors({ decodeError: true });\n }\n });\n }\n }\n\n sendPayment() {\n if (this.zeroAmtInvoice && this.paymentAmount) {\n this.store.dispatch(sendPayment({ payload: { invoice: this.paymentRequest, amountMsat: this.paymentAmount * 1000, fromDialog: true } }));\n } else {\n this.store.dispatch(sendPayment({ payload: { invoice: this.paymentRequest, fromDialog: true } }));\n }\n }\n\n onPaymentRequestEntry(event: any) {\n this.paymentRequest = event && typeof event === 'string' ? event.trim() : event;\n this.paymentError = '';\n this.paymentDecodedHint = '';\n this.zeroAmtInvoice = false;\n if (this.paymentRequest && this.paymentRequest.length > 100) {\n this.paymentReq.control.setErrors(null);\n this.zeroAmtInvoice = false;\n this.dataService.decodePayment(this.paymentRequest, true).\n pipe(take(1)).subscribe({\n next: (decodedPayment: PayRequest) => {\n this.paymentDecoded = decodedPayment;\n if (this.paymentDecoded.timestamp && !this.paymentDecoded.amount) {\n this.paymentDecoded.amount = 0;\n this.zeroAmtInvoice = true;\n this.paymentDecodedHint = 'Zero Amount Invoice | Memo: ' + this.paymentDecoded.description;\n } else {\n this.zeroAmtInvoice = false;\n if (this.selNode && this.selNode.fiatConversion && this.paymentDecoded.amount) {\n this.commonService.convertCurrency(+this.paymentDecoded.amount, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).\n pipe(takeUntil(this.unSubs[3])).\n subscribe({\n next: (data) => {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount : 0) + ' Sats (' + data.symbol + this.decimalPipe.transform((data.OTHER ? data.OTHER : 0), CURRENCY_UNIT_FORMATS.OTHER) + ') | Memo: ' + this.paymentDecoded.description;\n }, error: (error) => {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount : 0) + ' Sats | Memo: ' + this.paymentDecoded.description + '. Unable to convert currency.';\n }\n });\n } else {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount : 0) + ' Sats | Memo: ' + this.paymentDecoded.description;\n }\n }\n }, error: (err) => {\n this.logger.error(err);\n this.paymentDecodedHint = 'ERROR: ' + ((err.message) ? err.message : ((typeof err === 'string') ? err : JSON.stringify(err)));\n this.paymentReq.control.setErrors({ decodeError: true });\n }\n });\n }\n }\n\n onAmountChange(event: any) {\n delete this.paymentDecoded.amount;\n this.paymentDecoded.amount = event;\n }\n\n resetData() {\n this.paymentDecoded = {};\n this.paymentRequest = '';\n this.selActiveChannel = null;\n this.feeLimit = null;\n this.selFeeLimitType = FEE_LIMIT_TYPES[0];\n this.paymentReq.control.setErrors(null);\n this.paymentError = '';\n this.paymentDecodedHint = '';\n this.zeroAmtInvoice = false;\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxLayout.gt-sm=\"row\" fxLayoutAlign=\"space-between stretch\">\n <div fxFlex=\"100\">\n <mat-card-header fxLayout=\"row\" fxLayoutAlign=\"space-between center\" class=\"modal-info-header\">\n <div fxFlex=\"95\" fxLayoutAlign=\"start start\">\n <span class=\"page-title\">Payment Information</span>\n </div>\n <button tabindex=\"3\" fxFlex=\"5\" fxLayoutAlign=\"center\" class=\"btn-close-x p-0\" mat-button (click)=\"onClose()\">X</button>\n </mat-card-header>\n <mat-card-content #scrollContainer class=\"h-40 padding-gap-x-large\" [perfectScrollbar]>\n <div fxLayout=\"column\">\n <div fxLayout=\"row\">\n <div fxFlex=\"30\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Amount (Sats)</h4>\n <span class=\"foreground-secondary-text\">{{payment.recipientAmount | number}}</span>\n </div>\n <div fxFlex=\"70\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Date/Time</h4>\n <span class=\"foreground-secondary-text\">{{(payment.firstPartTimestamp) | date:'dd/MMM/y HH:mm'}}</span>\n </div>\n </div>\n <mat-divider class=\"w-100 my-1\"></mat-divider> \n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">ID</h4>\n <span class=\"foreground-secondary-text\">{{payment.id}}</span>\n </div>\n </div>\n <mat-divider class=\"w-100 my-1\"></mat-divider> \n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Payment Hash</h4>\n <span class=\"foreground-secondary-text\">{{payment.paymentHash}}</span>\n </div>\n </div>\n <mat-divider class=\"w-100 my-1\"></mat-divider> \n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Payment Preimage</h4>\n <span class=\"foreground-secondary-text\">{{payment.paymentPreimage}}</span>\n </div>\n </div>\n <mat-divider class=\"w-100 my-1\"></mat-divider> \n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Recipient Node</h4>\n <span class=\"foreground-secondary-text\">{{payment.recipientNodeAlias}}</span>\n </div>\n </div>\n <mat-divider class=\"w-100 my-1\"></mat-divider> \n <div *ngIf=\"description\" fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Description</h4>\n <span class=\"foreground-secondary-text\">{{description}}</span>\n </div>\n </div>\n <mat-divider *ngIf=\"description\" class=\"w-100 my-1\"></mat-divider> \n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <mat-accordion>\n <mat-expansion-panel *ngFor=\"let part of payment.parts; index as i\" class=\"flat-expansion-panel my-1\" [expanded]=\"expansionOpen\" (opened)=\"onExpansionOpen(true)\" (closed)=\"onExpansionOpen(false)\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <h4 fxFlex=\"30\" fxLayoutAlign=\"start\" class=\"font-bold-500\">Part {{i + 1}}</h4>\n <h4 fxFlex=\"70\" fxLayoutAlign=\"start\" class=\"font-bold-500\">{{part.amount | number}} (Sats)</h4>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div fxLayout=\"column\">\n <div fxLayout=\"row\">\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Fees (mSats)</h4>\n <span class=\"foreground-secondary-text\">{{part.feesPaid | number}}</span>\n </div>\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Date/Time</h4>\n <span class=\"foreground-secondary-text\">{{(part.timestamp) | date:'dd/MMM/y HH:mm'}}</span>\n </div>\n </div>\n <mat-divider class=\"w-100 my-1\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">ID</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{part.id}}</span>\n </div>\n </div>\n <mat-divider class=\"w-100 my-1\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">To Channel</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{part.toChannelAlias}}</span>\n </div>\n </div>\n </div>\n </mat-expansion-panel>\n </mat-accordion> \n </div>\n </div>\n </div>\n </mat-card-content>\n <div fxLayout=\"row\" fxLayoutAlign=\"start end\" class=\"btn-sticky-container padding-gap-x-large\">\n <button mat-mini-fab aria-label=\"Scroll Down\" fxLayoutAlign=\"center center\" (click)=\"onScrollDown()\">\n <mat-icon fxLayoutAlign=\"center center\">arrow_downward</mat-icon>\n </button>\n </div>\n <div fxLayout=\"row\" fxLayoutAlign=\"end center\" class=\"padding-gap-x-large padding-gap-bottom-large\">\n <button class=\"mr-1\" fxLayoutAlign=\"center center\" tabindex=\"1\" mat-button color=\"primary\" type=\"button\" default [mat-dialog-close]=\"false\">OK</button>\n </div>\n </div>\n</div>\n","import { Component, OnInit, Inject, AfterViewChecked, ViewChild, ElementRef } from '@angular/core';\nimport { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';\n\nimport { PaymentSent } from '../../../shared/models/eclModels';\nimport { ECLPaymentInformation } from '../../../shared/models/alertData';\n\n@Component({\n selector: 'rtl-ecl-payment-information',\n templateUrl: './payment-information.component.html',\n styleUrls: ['./payment-information.component.scss']\n})\nexport class ECLPaymentInformationComponent implements OnInit, AfterViewChecked {\n\n @ViewChild('scrollContainer', { static: false }) scrollContainer: ElementRef;\n public payment: PaymentSent;\n public description: string | null = null;\n public shouldScroll = true;\n public expansionOpen = true;\n\n constructor(public dialogRef: MatDialogRef<ECLPaymentInformationComponent>, @Inject(MAT_DIALOG_DATA) public data: ECLPaymentInformation) { }\n\n ngOnInit() {\n this.payment = this.data.payment;\n if (this.data.sentPaymentInfo.length > 0 && this.data.sentPaymentInfo[0].paymentRequest && this.data.sentPaymentInfo[0].paymentRequest.description && this.data.sentPaymentInfo[0].paymentRequest.description !== '') {\n this.description = this.data.sentPaymentInfo[0].paymentRequest.description;\n }\n }\n\n ngAfterViewChecked() {\n this.shouldScroll = this.scrollContainer.nativeElement.classList.value.includes('ps--active-y');\n }\n\n onScrollDown() {\n this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollTop + 62.6;\n }\n\n onExpansionOpen(opened: boolean) {\n this.expansionOpen = opened;\n }\n\n onClose() {\n this.dialogRef.close(false);\n }\n\n}\n","<div fxLayout=\"column\" fxFlex=\"colWidth\" fxLayoutAlign=\"space-between stretch\">\n <form *ngIf=\"calledFrom === 'home'\" #sendPaymentForm=\"ngForm\" fxLayout=\"column\" fxLayoutAlign=\"space-between stretch\" fxLayout.gt-sm=\"row wrap\">\n <mat-form-field fxFlex=\"colWidth\">\n <textarea #paymentReq=\"ngModel\" matInput placeholder=\"Payment Request\" name=\"paymentRequest\" tabindex=\"1\" required [perfectScrollbar] [ngModel]=\"paymentRequest\" (ngModelChange)=\"onPaymentRequestEntry($event)\" (matTextareaAutosize)=\"true\"></textarea>\n <mat-hint *ngIf=\"paymentRequest && paymentDecodedHint !== ''\">{{paymentDecodedHint}}</mat-hint>\n <mat-error *ngIf=\"!paymentRequest\">Payment request is required.</mat-error>\n </mat-form-field>\n <div fxLayout=\"row\" class=\"mt-1\">\n <button class=\"mr-1\" mat-stroked-button color=\"primary\" tabindex=\"2\" type=\"reset\" (click)=\"resetData()\">Clear Field</button>\n <button mat-flat-button color=\"primary\" tabindex=\"3\" (click)=\"onSendPayment()\">Send Payment</button>\n </div>\n </form>\n <div *ngIf=\"calledFrom === 'transactions'\" fxLayout=\"row\">\n <button mat-flat-button color=\"primary\" tabindex=\"3\" (click)=\"openSendPaymentModal()\">Send Payment</button>\n </div>\n <div *ngIf=\"calledFrom === 'transactions'\" fxLayout=\"column\" fxLayoutAlign=\"start stretch\">\n <div fxLayout=\"column\" fxLayoutAlign=\"start stretch\" fxLayout.gt-sm=\"row wrap\" class=\"page-sub-title-container mt-1\">\n <div fxFlex=\"70\" fxLayoutAlign=\"start start\" fxLayoutAlign.gt-sm=\"start center\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faHistory\"></fa-icon>\n <span class=\"page-title\">Payments History</span>\n </div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput name=\"filter\" placeholder=\"Filter\" [(ngModel)]=\"selFilter\" (input)=\"applyFilter()\" (keyup)=\"applyFilter()\">\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"row\" fxLayoutAlign=\"start start\">\n <div fxLayout=\"column\" fxLayoutAlign=\"start center\" fxFlex=\"colWidth\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #table mat-table fxFlex=\"colWidth\" matSort [dataSource]=\"payments\" [ngClass]=\"{'error-border': errorMessage !== ''}\">\n <ng-container matColumnDef=\"firstPartTimestamp\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Date/Time</th>\n <td *matCellDef=\"let payment\" mat-cell>{{payment?.firstPartTimestamp | date:'dd/MMM/y HH:mm'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"id\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>ID</th>\n <td *matCellDef=\"let payment\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.id}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"recipientNodeId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Destination Node ID</th>\n <td *matCellDef=\"let payment\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.recipientNodeId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"recipientNodeAlias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Destination</th>\n <td *matCellDef=\"let payment\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.recipientNodeAlias}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"description\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Description</th>\n <td *matCellDef=\"let payment\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.description}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"paymentHash\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Payment Hash</th>\n <td *matCellDef=\"let payment\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.paymentHash}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"paymentPreimage\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Preimage</th>\n <td *matCellDef=\"let payment\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.paymentPreimage}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"recipientAmount\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Amount (Sats)</th>\n <td *matCellDef=\"let payment\" mat-cell><span fxLayoutAlign=\"end center\">{{(payment?.recipientAmount) | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onDownloadCSV()\">Download CSV</mat-option>\n </mat-select>\n </div>\n </th>\n <td *matCellDef=\"let payment\" mat-cell fxLayoutAlign=\"end center\">\n <button mat-stroked-button color=\"primary\" type=\"button\" tabindex=\"4\" class=\"table-actions-button\" (click)=\"onPaymentClick(payment)\">View Info</button> \n </td>\n </ng-container>\n <ng-container matColumnDef=\"no_payment\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!payments?.data || payments?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No payment available.</p>\n <p *ngIf=\"(!payments?.data || payments?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting payments...</p>\n <p *ngIf=\"(!payments?.data || payments?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n\n <!-- Payment Group Row Start -->\n <ng-container matColumnDef=\"group_firstPartTimestamp\">\n <td *matCellDef=\"let payment\" mat-cell>\n <span fxLayoutAlign=\"start center\" class=\"part-row-span\">\n Total Attempts: {{payment?.parts?.length || 0}}\n </span>\n <ng-container *ngIf=\"payment?.is_expanded\">\n <span *ngFor=\"let part of payment?.parts\" fxLayoutAlign=\"start center\" class=\"part-row-span\">\n {{part.timestamp | date:'dd/MMM/y HH:mm'}}\n </span>\n </ng-container>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"group_id\">\n <td *matCellDef=\"let payment\" mat-cell>\n <div fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.id}}</span>\n </div>\n <span *ngIf=\"payment?.is_expanded\">\n <span *ngFor=\"let part of payment?.parts\" fxLayoutAlign=\"start center\" class=\"part-row-span\">\n <span fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{part.id}}</span>\n </span>\n </span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"group_recipientNodeId\">\n <td *matCellDef=\"let payment\" mat-cell>\n <div fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.recipientNodeId}}</span>\n </div>\n <span *ngIf=\"payment?.is_expanded\">\n <span *ngFor=\"let part of payment?.parts\" fxLayoutAlign=\"start center\" class=\"part-row-span\">\n <span fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{part.toChannelId}}</span>\n </span>\n </span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"group_recipientNodeAlias\">\n <td *matCellDef=\"let payment\" mat-cell>\n <div fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.recipientNodeAlias}}</span>\n </div>\n <span *ngIf=\"payment?.is_expanded\">\n <span *ngFor=\"let part of payment?.parts\" fxLayoutAlign=\"start center\" class=\"part-row-span\">\n <span fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{part.toChannelAlias}}</span>\n </span>\n </span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"group_recipientAmount\">\n <td *matCellDef=\"let payment\" mat-cell>\n <span fxLayoutAlign=\"end center\" class=\"part-row-span\">{{payment?.recipientAmount | number:'1.0-0'}}</span>\n <span *ngIf=\"payment?.is_expanded\">\n <span *ngFor=\"let part of payment?.parts\" fxLayoutAlign=\"end center\" class=\"part-row-span\">\n {{part.amount | number:'1.0-0'}}\n </span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"group_description\">\n <td *matCellDef=\"let payment\" mat-cell>\n <div fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.description}}</span>\n </div>\n <span *ngIf=\"payment?.is_expanded\">\n <span *ngFor=\"let part of payment?.parts\" fxLayoutAlign=\"start center\" class=\"part-row-span\">\n <span fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">Fee Paid: {{part.feesPaid | number:'1.0-0'}} (Sats)</span>\n </span>\n </span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"group_paymentHash\">\n <td *matCellDef=\"let payment\" mat-cell>\n <div fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.paymentHash}}</span>\n </div>\n <span *ngIf=\"payment?.is_expanded\">\n <span *ngFor=\"let part of payment?.parts\" fxLayoutAlign=\"start center\" class=\"part-row-span\">\n <span fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">Fee Paid: {{part.feesPaid | number:'1.0-0'}} (Sats)</span>\n </span>\n </span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"group_paymentPreimage\">\n <td *matCellDef=\"let payment\" mat-cell>\n <div fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{payment?.paymentPreimage}}</span>\n </div>\n <span *ngIf=\"payment?.is_expanded\">\n <span *ngFor=\"let part of payment?.parts\" fxLayoutAlign=\"start center\" class=\"part-row-span\">\n <span fxLayoutAlign=\"start center\" class=\"ellipsis-parent part-row-span\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">Fee Paid: {{part.feesPaid | number:'1.0-0'}} (Sats)</span>\n </span>\n </span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"group_actions\">\n <td *matCellDef=\"let payment\" mat-cell>\n <span fxLayoutAlign=\"end start\">\n <button mat-flat-button class=\"btn-part-expand\" color=\"primary\" type=\"button\" tabindex=\"5\" (click)=\"payment.is_expanded = !payment.is_expanded\">{{payment?.is_expanded ? 'Hide' : 'Show'}}</button>\n </span>\n <div *ngIf=\"payment?.is_expanded\">\n <div *ngFor=\"let part of payment?.parts; index as i\" fxLayoutAlign=\"end start\">\n <button mat-stroked-button class=\"btn-part-info\" color=\"primary\" type=\"button\" tabindex=\"6\" (click)=\"onPartClick(part, payment)\">View {{i + 1}}</button>\n </div>\n </div>\n </td>\n </ng-container>\n <tr *matRowDef=\"let row; columns: partColumns; when: is_group;\" mat-row></tr>\n <!-- Payment Group Row End -->\n\n <tr *matFooterRowDef=\"['no_payment']\" mat-footer-row [ngClass]=\"{'display-none': payments?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div>\n </div>\n <mat-paginator class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild, Input, AfterViewInit } from '@angular/core';\nimport { DecimalPipe, DatePipe } from '@angular/common';\nimport { Subject } from 'rxjs';\nimport { takeUntil, take } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { faHistory } from '@fortawesome/free-solid-svg-icons';\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\n\nimport { GetInfo, PayRequest, PaymentSent, PaymentSentPart, Payments } from '../../../shared/models/eclModels';\nimport { 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';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { CommonService } from '../../../shared/services/common.service';\nimport { DataService } from '../../../shared/services/data.service';\n\nimport { ECLLightningSendPaymentsComponent } from '../send-payment-modal/send-payment.component';\nimport { ECLPaymentInformationComponent } from '../payment-information-modal/payment-information.component';\nimport { SelNodeChild } from '../../../shared/models/RTLconfig';\n\nimport { RTLEffects } from '../../../store/rtl.effects';\nimport { RTLState } from '../../../store/rtl.state';\nimport { openAlert, openConfirmation } from '../../../store/rtl.actions';\nimport { sendPayment } from '../../store/ecl.actions';\nimport { eclNodeInformation, eclNodeSettings, eclPageSettings, payments } from '../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../shared/pipes/app.pipe';\n\n@Component({\n selector: 'rtl-ecl-lightning-payments',\n templateUrl: './lightning-payments.component.html',\n styleUrls: ['./lightning-payments.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Payments') }\n ]\n})\nexport class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnDestroy {\n\n @Input() calledFrom = 'transactions'; // Transactions/home\n @ViewChild('sendPaymentForm', { static: false }) form;\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterBy = 'all';\n public colWidth = '20rem';\n public PAGE_ID = 'transactions';\n public tableSetting: TableSetting = { tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'firstPartTimestamp', sortOrder: SortOrderEnum.DESCENDING };\n public faHistory = faHistory;\n public newlyAddedPayment = '';\n public selNode: SelNodeChild | null = {};\n public information: GetInfo = {};\n public payments: any = new MatTableDataSource<PaymentSent>([]);\n public paymentJSONArr: PaymentSent[] = [];\n public paymentDecoded: PayRequest = {};\n public displayedColumns: any[] = [];\n public partColumns: string[] = [];\n public paymentRequest = '';\n public paymentDecodedHint = '';\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public selFilter = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private decimalPipe: DecimalPipe, private dataService: DataService, private datePipe: DatePipe, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((nodeSettings: SelNodeChild | null) => {\n this.selNode = nodeSettings;\n });\n this.store.select(eclNodeInformation).pipe(takeUntil(this.unSubs[1])).\n subscribe((nodeInfo: GetInfo) => {\n this.information = nodeInfo;\n });\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[2])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.push('actions');\n this.partColumns = [];\n this.displayedColumns.map((col) => this.partColumns.push('group_' + col));\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n this.store.select(payments).pipe(takeUntil(this.unSubs[3])).\n subscribe((paymentsSeletor: { payments: Payments, apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = paymentsSeletor.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n this.paymentJSONArr = (paymentsSeletor.payments && paymentsSeletor.payments.sent && paymentsSeletor.payments.sent.length > 0) ? paymentsSeletor.payments.sent : [];\n if (this.paymentJSONArr.length > 0 && this.sort && this.paginator && this.displayedColumns.length > 0) {\n this.loadPaymentsTable(this.paymentJSONArr);\n }\n this.logger.info(paymentsSeletor);\n });\n }\n\n ngAfterViewInit() {\n if (this.paymentJSONArr.length > 0) {\n this.loadPaymentsTable(this.paymentJSONArr);\n }\n }\n\n applyFilter() {\n this.payments.filter = this.selFilter.trim().toLowerCase();\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column, '_') : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.payments.filterPredicate = (rowData: PaymentSent, fltr: string) => {\n let rowToFilter = '';\n switch (this.selFilterBy) {\n case 'all':\n rowToFilter = ((rowData.firstPartTimestamp) ? this.datePipe.transform(new Date(rowData.firstPartTimestamp), 'dd/MMM/y HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();\n break;\n\n case 'firstPartTimestamp':\n rowToFilter = this.datePipe.transform(new Date(rowData.firstPartTimestamp || 0), 'dd/MMM/y HH:mm')?.toLowerCase() || '';\n break;\n\n default:\n rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();\n break;\n }\n return rowToFilter.includes(fltr);\n };\n }\n\n loadPaymentsTable(payms: PaymentSent[]) {\n this.payments = payms ? new MatTableDataSource<PaymentSent>([...payms]) : new MatTableDataSource<PaymentSent>([]);\n this.payments.sort = this.sort;\n this.payments.sortingDataAccessor = (data: any, sortHeaderId: string) => {\n switch (sortHeaderId) {\n case 'firstPartTimestamp':\n this.commonService.sortByKey(data.parts, 'timestamp', 'number', this.sort?.direction);\n return data.firstPartTimestamp;\n\n case 'id':\n this.commonService.sortByKey(data.parts, 'id', 'string', this.sort?.direction);\n return data.id;\n\n case 'recipientNodeAlias':\n this.commonService.sortByKey(data.parts, 'toChannelAlias', 'string', this.sort?.direction);\n return data.recipientNodeAlias;\n\n case 'recipientAmount':\n this.commonService.sortByKey(data.parts, 'amount', 'number', this.sort?.direction);\n return data.recipientAmount;\n\n default:\n return (data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null;\n }\n };\n this.payments.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.payments.paginator = this.paginator;\n this.setFilterPredicate();\n this.applyFilter();\n }\n\n onSendPayment(): boolean | void {\n if (!this.paymentRequest) {\n return true;\n }\n if (this.paymentDecoded.timestamp) {\n this.sendPayment();\n } else {\n this.dataService.decodePayment(this.paymentRequest, false).\n pipe(take(1)).subscribe((decodedPayment: PayRequest) => {\n this.paymentDecoded = decodedPayment;\n if (this.paymentDecoded.timestamp) {\n if (!this.paymentDecoded.amount) {\n this.paymentDecoded.amount = 0;\n }\n this.sendPayment();\n } else {\n this.resetData();\n }\n });\n }\n }\n\n sendPayment() {\n this.newlyAddedPayment = this.paymentDecoded.paymentHash || '';\n if (!this.paymentDecoded.amount || this.paymentDecoded.amount === 0) {\n const reorderedPaymentDecoded = [\n [{ key: 'paymentHash', value: this.paymentDecoded.paymentHash, title: 'Payment Hash', width: 100 }],\n [{ key: 'nodeId', value: this.paymentDecoded.nodeId, title: 'Payee', width: 100 }],\n [{ key: 'description', value: this.paymentDecoded.description, title: 'Description', width: 100 }],\n [{ key: 'timestamp', value: this.paymentDecoded.timestamp, title: 'Creation Date', width: 40, type: DataTypeEnum.DATE_TIME },\n { key: 'expiry', value: this.paymentDecoded.expiry, title: 'Expiry', width: 30, type: DataTypeEnum.NUMBER },\n { key: 'minFinalCltvExpiry', value: this.paymentDecoded.minFinalCltvExpiry, title: 'CLTV Expiry', width: 30 }]\n ];\n const titleMsg = 'It is a zero amount invoice. Enter the amount (Sats) to pay.';\n this.store.dispatch(openConfirmation({\n payload: {\n data: {\n type: AlertTypeEnum.CONFIRM,\n alertTitle: 'Enter Amount and Confirm Send Payment',\n message: reorderedPaymentDecoded,\n noBtnText: 'Cancel',\n yesBtnText: 'Send Payment',\n flgShowInput: true,\n titleMessage: titleMsg,\n getInputs: [\n { placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER, inputValue: '', width: 30 }\n ]\n }\n }\n }));\n this.rtlEffects.closeConfirm.\n pipe(take(1)).\n subscribe((confirmRes) => {\n if (confirmRes) {\n this.paymentDecoded.amount = confirmRes[0].inputValue;\n this.store.dispatch(sendPayment({ payload: { invoice: this.paymentRequest, amountMsat: confirmRes[0].inputValue * 1000, fromDialog: false } }));\n this.resetData();\n }\n });\n } else {\n const reorderedPaymentDecoded = [\n [{ key: 'paymentHash', value: this.paymentDecoded.paymentHash, title: 'Payment Hash', width: 100 }],\n [{ key: 'nodeId', value: this.paymentDecoded.nodeId, title: 'Payee', width: 100 }],\n [{ key: 'description', value: this.paymentDecoded.description, title: 'Description', width: 100 }],\n [{ key: 'timestamp', value: this.paymentDecoded.timestamp, title: 'Creation Date', width: 50, type: DataTypeEnum.DATE_TIME },\n { key: 'amount', value: this.paymentDecoded.amount, title: 'Amount (Sats)', width: 50, type: DataTypeEnum.NUMBER }],\n [{ key: 'expiry', value: this.paymentDecoded.expiry, title: 'Expiry', width: 50, type: DataTypeEnum.NUMBER },\n { key: 'minFinalCltvExpiry', value: this.paymentDecoded.minFinalCltvExpiry, title: 'CLTV Expiry', width: 50 }]\n ];\n this.store.dispatch(openConfirmation({\n payload: {\n data: {\n type: AlertTypeEnum.CONFIRM,\n alertTitle: 'Confirm Send Payment',\n noBtnText: 'Cancel',\n yesBtnText: 'Send Payment',\n message: reorderedPaymentDecoded\n }\n }\n }));\n this.rtlEffects.closeConfirm.\n pipe(take(1)).\n subscribe((confirmRes) => {\n if (confirmRes) {\n this.store.dispatch(sendPayment({ payload: { invoice: this.paymentRequest, fromDialog: false } }));\n this.resetData();\n }\n });\n }\n }\n\n onPaymentRequestEntry(event: any) {\n this.paymentRequest = event;\n this.paymentDecodedHint = '';\n if (this.paymentRequest && this.paymentRequest.length > 100) {\n this.dataService.decodePayment(this.paymentRequest, false).\n pipe(take(1)).subscribe((decodedPayment: PayRequest) => {\n this.paymentDecoded = decodedPayment;\n if (this.paymentDecoded.amount) {\n if (this.selNode && this.selNode.fiatConversion) {\n this.commonService.convertCurrency(+this.paymentDecoded.amount, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).\n pipe(takeUntil(this.unSubs[4])).\n subscribe({\n next: (data) => {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount : 0) + ' Sats (' + data.symbol + this.decimalPipe.transform((data.OTHER ? data.OTHER : 0), CURRENCY_UNIT_FORMATS.OTHER) + ') | Memo: ' + this.paymentDecoded.description;\n }, error: (error) => {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount : 0) + ' Sats | Memo: ' + this.paymentDecoded.description + '. Unable to convert currency.';\n }\n });\n } else {\n this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount ? this.paymentDecoded.amount : 0) + ' Sats | Memo: ' + this.paymentDecoded.description;\n }\n } else {\n this.paymentDecodedHint = 'Zero Amount Invoice | Memo: ' + this.paymentDecoded.description;\n }\n });\n }\n }\n\n openSendPaymentModal() {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n component: ECLLightningSendPaymentsComponent\n }\n }\n }));\n }\n\n resetData() {\n this.paymentDecoded = {};\n this.paymentRequest = '';\n this.form.resetForm();\n }\n\n is_group(index: number, payment: PaymentSent): boolean {\n return payment.parts && payment.parts.length > 1;\n }\n\n onPaymentClick(selPayment: PaymentSent) {\n if (selPayment.paymentHash && selPayment.paymentHash.trim() !== '') {\n this.dataService.decodePayments(selPayment.paymentHash).\n pipe(take(1)).\n subscribe({\n next: (sentPaymentInfo) => {\n setTimeout(() => {\n this.showPaymentView(selPayment, (sentPaymentInfo.length && sentPaymentInfo.length > 0) ? sentPaymentInfo[0] : []);\n }, 0);\n }, error: (error) => {\n this.showPaymentView(selPayment, []);\n }\n });\n } else {\n this.showPaymentView(selPayment, []);\n }\n }\n\n showPaymentView(selPayment: PaymentSent, sentPaymentInfo?: any[]) {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n sentPaymentInfo: sentPaymentInfo,\n payment: selPayment,\n component: ECLPaymentInformationComponent\n }\n }\n }));\n }\n\n onPartClick(selPart: PaymentSentPart, selPayment: PaymentSent) {\n if (selPayment.paymentHash && selPayment.paymentHash.trim() !== '') {\n this.dataService.decodePayments(selPayment.paymentHash).\n pipe(take(1)).\n subscribe({\n next: (sentPaymentInfo) => {\n setTimeout(() => {\n this.showPartView(selPart, selPayment, (sentPaymentInfo.length && sentPaymentInfo.length > 0) ? sentPaymentInfo[0] : []);\n }, 0);\n }, error: (error) => {\n this.showPartView(selPart, selPayment, []);\n }\n });\n } else {\n this.showPartView(selPart, selPayment, []);\n }\n }\n\n showPartView(selPart: PaymentSentPart, selPayment: PaymentSent, sentPaymentInfo?: any[]) {\n const reorderedPart = [\n [{ key: 'paymentHash', value: selPayment.paymentHash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }],\n [{ key: 'paymentPreimage', value: selPayment.paymentPreimage, title: 'Payment Preimage', width: 100, type: DataTypeEnum.STRING }],\n [{ key: 'toChannelId', value: selPart.toChannelId, title: 'Channel', width: 100, type: DataTypeEnum.STRING }],\n [{ key: 'id', value: selPart.id, title: 'Part ID', width: 50, type: DataTypeEnum.STRING },\n { key: 'timestamp', value: selPart.timestamp, title: 'Time', width: 50, type: DataTypeEnum.DATE_TIME }],\n [{ key: 'amount', value: selPart.amount, title: 'Amount (Sats)', width: 50, type: DataTypeEnum.NUMBER },\n { key: 'feesPaid', value: selPart.feesPaid, title: 'Fee (Sats)', width: 50, type: DataTypeEnum.NUMBER }]\n ];\n if (sentPaymentInfo && sentPaymentInfo.length > 0 && sentPaymentInfo[0].paymentRequest && sentPaymentInfo[0].paymentRequest.description && sentPaymentInfo[0].paymentRequest.description !== '') {\n reorderedPart.splice(3, 0, [{ key: 'description', value: sentPaymentInfo[0].paymentRequest.description, title: 'Description', width: 100, type: DataTypeEnum.STRING }]);\n }\n this.store.dispatch(openAlert({\n payload: {\n data: {\n type: AlertTypeEnum.INFORMATION,\n alertTitle: 'Payment Part Information',\n message: reorderedPart\n }\n }\n }));\n }\n\n onDownloadCSV() {\n if (this.payments.data && this.payments.data.length > 0) {\n const paymentsDataCopy: PaymentSent[] = JSON.parse(JSON.stringify(this.payments.data));\n const paymentRequests = paymentsDataCopy?.reduce((paymentReqs, payment) => {\n if (payment.paymentHash && payment.paymentHash.trim() !== '') {\n paymentReqs = (paymentReqs === '') ? payment.paymentHash : paymentReqs + ',' + payment.paymentHash;\n }\n return paymentReqs;\n }, '');\n this.dataService.decodePayments(paymentRequests).\n pipe(takeUntil(this.unSubs[5])).\n subscribe((decodedPayments: any[][]) => {\n decodedPayments.forEach((decodedPayment, idx) => {\n if (decodedPayment.length > 0 && decodedPayment[0].paymentRequest && decodedPayment[0].paymentRequest.description && decodedPayment[0].paymentRequest.description !== '') {\n paymentsDataCopy[idx].description = decodedPayment[0].paymentRequest.description;\n }\n });\n const flattenedPayments = paymentsDataCopy?.reduce((acc, curr: any) => acc.concat(curr), []);\n this.commonService.downloadFile(flattenedPayments, 'Payments');\n });\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <mat-card-header fxLayout=\"row\" fxLayoutAlign=\"space-between center\" class=\"modal-info-header\">\n <div fxFlex=\"95\" fxLayoutAlign=\"start start\">\n <span class=\"page-title\">Create Invoice</span>\n </div>\n <button tabindex=\"8\" fxFlex=\"5\" fxLayoutAlign=\"center\" class=\"btn-close-x p-0\" default mat-button [mat-dialog-close]=\"false\">X</button>\n </mat-card-header>\n <mat-card-content class=\"padding-gap-x-large\">\n <form #addInvoiceForm=\"ngForm\" fxLayout=\"row wrap\" fxLayoutAlign=\"start space-between\" fxFlex=\"100\">\n <mat-form-field fxFlex=\"100\" fxLayoutAlign=\"start end\">\n <input matInput autoFocus placeholder=\"Description\" tabindex=\"2\" name=\"description\" required [(ngModel)]=\"description\">\n <mat-error *ngIf=\"!description\">Description is required.</mat-error>\n </mat-form-field>\n <div fxLayout=\"row\" fxLayoutAlign=\"space-between start\" fxFlex=\"100\">\n <mat-form-field fxFlex=\"40\">\n <input matInput placeholder=\"Amount\" type=\"number\" tabindex=\"3\" name=\"invValue\" [step]=\"100\" [min]=\"1\" [(ngModel)]=\"invoiceValue\" (keyup)=\"onInvoiceValueChange()\">\n <span matSuffix> Sats </span>\n <mat-hint>{{invoiceValueHint}}</mat-hint>\n </mat-form-field>\n <mat-form-field fxFlex=\"30\">\n <input matInput placeholder=\"Expiry\" type=\"number\" name=\"exp\" tabindex=\"4\" [step]=\"selTimeUnit === timeUnitEnum.SECS ? 300 : selTimeUnit === timeUnitEnum.MINS ? 10 : selTimeUnit === timeUnitEnum.HOURS ? 2 : 1\" [min]=\"1\" [(ngModel)]=\"expiry\">\n <span matSuffix>{{selTimeUnit | titlecase}} </span>\n </mat-form-field>\n <mat-form-field fxFlex=\"26\">\n <mat-select tabindex=\"5\" name=\"timeUnit\" [value]=\"selTimeUnit\" (selectionChange)=\"onTimeUnitChange($event)\">\n <mat-option *ngFor=\"let timeUnit of timeUnits\" [value]=\"timeUnit\">{{timeUnit | titlecase}}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div *ngIf=\"invoiceError !== ''\" fxFlex=\"100\" class=\"alert alert-danger mt-1\">\n <fa-icon class=\"mr-1 alert-icon\" [icon]=\"faExclamationTriangle\"></fa-icon>\n <span *ngIf=\"invoiceError !== ''\">{{invoiceError}}</span>\n </div>\n <div fxLayout=\"row\" fxFlex=\"100\" class=\"mt-2\" fxLayoutAlign=\"end center\">\n <button class=\"mr-1\" mat-button color=\"primary\" tabindex=\"7\" type=\"reset\" (click)=\"resetData()\">Clear Field</button>\n <button mat-button color=\"primary\" tabindex=\"8\" (click)=\"onAddInvoice(addInvoiceForm)\">Create Invoice</button>\n </div>\n </form>\n </mat-card-content>\n </div> \n</div>\n","import { Component, OnInit, OnDestroy, Inject } from '@angular/core';\nimport { DecimalPipe } from '@angular/common';\nimport { Subject } from 'rxjs';\nimport { filter, takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { Actions } from '@ngrx/effects';\nimport { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';\nimport { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';\n\nimport { ECLInvoiceInformation } from '../../../shared/models/alertData';\nimport { TimeUnitEnum, CurrencyUnitEnum, TIME_UNITS, CURRENCY_UNIT_FORMATS, PAGE_SIZE, APICallStatusEnum, ECLActions } from '../../../shared/services/consts-enums-functions';\nimport { SelNodeChild } from '../../../shared/models/RTLconfig';\nimport { GetInfo } from '../../../shared/models/eclModels';\nimport { CommonService } from '../../../shared/services/common.service';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { createInvoice } from '../../store/ecl.actions';\nimport { eclNodeInformation, eclNodeSettings } from '../../store/ecl.selector';\n\n@Component({\n selector: 'rtl-ecl-create-invoices',\n templateUrl: './create-invoice.component.html',\n styleUrls: ['./create-invoice.component.scss']\n})\nexport class ECLCreateInvoiceComponent implements OnInit, OnDestroy {\n\n public faExclamationTriangle = faExclamationTriangle;\n public selNode: SelNodeChild | null = {};\n public description = '';\n public expiry: number | null;\n public invoiceValue: number | null = null;\n public invoiceValueHint = '';\n public invoicePaymentReq = '';\n public information: GetInfo = {};\n public private = false;\n public expiryStep = 100;\n public pageSize = PAGE_SIZE;\n public timeUnitEnum = TimeUnitEnum;\n public timeUnits = TIME_UNITS;\n public selTimeUnit = TimeUnitEnum.SECS;\n public invoiceError = '';\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(public dialogRef: MatDialogRef<ECLCreateInvoiceComponent>, @Inject(MAT_DIALOG_DATA) public data: ECLInvoiceInformation, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private actions: Actions) { }\n\n ngOnInit() {\n this.pageSize = this.data.pageSize;\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((nodeSettings: SelNodeChild | null) => {\n this.selNode = nodeSettings;\n });\n this.store.select(eclNodeInformation).pipe(takeUntil(this.unSubs[1])).\n subscribe((nodeInfo: any) => {\n this.information = <GetInfo>nodeInfo;\n });\n this.actions.pipe(\n takeUntil(this.unSubs[2]),\n filter((action) => action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL)).\n subscribe((action: any) => {\n if (action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL && action.payload.action === 'CreateInvoice') {\n if (action.payload.status === APICallStatusEnum.ERROR) {\n this.invoiceError = action.payload.message;\n }\n if (action.payload.status === APICallStatusEnum.COMPLETED) {\n this.dialogRef.close();\n }\n }\n });\n }\n\n onAddInvoice(form: any): boolean | void {\n this.invoiceError = '';\n if (!this.description) {\n return true;\n }\n let expiryInSecs = (this.expiry ? this.expiry : 3600);\n if (this.expiry && this.selTimeUnit !== TimeUnitEnum.SECS) {\n expiryInSecs = this.commonService.convertTime(this.expiry, this.selTimeUnit, TimeUnitEnum.SECS);\n }\n let invoicePayload: any = null;\n if (this.invoiceValue) {\n invoicePayload = { description: this.description, expireIn: expiryInSecs, amountMsat: this.invoiceValue * 1000 };\n } else {\n invoicePayload = { description: this.description, expireIn: expiryInSecs };\n }\n this.store.dispatch(createInvoice({ payload: invoicePayload }));\n }\n\n resetData() {\n this.description = '';\n this.invoiceValue = null;\n this.private = false;\n this.expiry = null;\n this.invoiceValueHint = '';\n this.selTimeUnit = TimeUnitEnum.SECS;\n this.invoiceError = '';\n }\n\n onInvoiceValueChange() {\n if (this.selNode && this.selNode.fiatConversion && this.invoiceValue && this.invoiceValue > 99) {\n this.invoiceValueHint = '';\n this.commonService.convertCurrency(this.invoiceValue, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).\n pipe(takeUntil(this.unSubs[3])).\n subscribe({\n next: (data) => {\n this.invoiceValueHint = '= ' + data.symbol + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;\n }, error: (err) => {\n this.invoiceValueHint = 'Conversion Error: ' + err;\n }\n });\n }\n }\n\n onTimeUnitChange(event: any) {\n if (this.expiry && this.selTimeUnit !== event.value) {\n this.expiry = this.commonService.convertTime(this.expiry, this.selTimeUnit, event.value);\n }\n this.selTimeUnit = event.value;\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start stretch\">\n <form *ngIf=\"calledFrom === 'home'\" #addInvoiceForm=\"ngForm\" fxLayout=\"row wrap\" fxLayoutAlign=\"stretch start\" fxFlex=\"100\">\n <mat-form-field fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <input matInput placeholder=\"Description\" tabindex=\"2\" name=\"description\" required=\"true\" [(ngModel)]=\"description\">\n <mat-error *ngIf=\"!description\">Description is required.</mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"100\" fxLayoutAlign=\"start end\">\n <input #invcVal=\"ngModel\" matInput placeholder=\"Amount\" type=\"number\" tabindex=\"3\" name=\"invValue\" [step]=\"100\" [min]=\"1\" [(ngModel)]=\"invoiceValue\" (keyup)=\"onInvoiceValueChange()\">\n <span matSuffix> Sats </span>\n <mat-hint>{{invoiceValueHint}}</mat-hint>\n </mat-form-field>\n <div fxLayout=\"row\" class=\"mt-1\">\n <button class=\"mr-1\" mat-stroked-button color=\"primary\" tabindex=\"9\" type=\"reset\" (click)=\"resetData()\">Clear Field</button>\n <button mat-flat-button color=\"primary\" tabindex=\"10\" (click)=\"onAddInvoice(addInvoiceForm)\">Create Invoice</button>\n </div>\n </form>\n <div *ngIf=\"calledFrom === 'transactions'\" fxLayout=\"row\">\n <button mat-flat-button color=\"primary\" tabindex=\"8\" (click)=\"openCreateInvoiceModal()\">Create Invoice</button>\n </div>\n <div *ngIf=\"calledFrom === 'transactions'\" fxLayout=\"column\" fxLayoutAlign=\"start stretch\">\n <div fxLayout=\"column\" fxLayoutAlign=\"start stretch\" fxLayout.gt-sm=\"row wrap\" class=\"page-sub-title-container mt-1\">\n <div fxFlex=\"70\" fxLayoutAlign=\"start start\" fxLayoutAlign.gt-sm=\"start center\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faHistory\"></fa-icon>\n <span class=\"page-title\">Invoices History</span>\n </div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput name=\"filter\" placeholder=\"Filter\" [(ngModel)]=\"selFilter\" (input)=\"applyFilter()\" (keyup)=\"applyFilter()\">\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #table mat-table fxFlex=\"100\" matSort [dataSource]=\"invoices\" [ngClass]=\"{'error-border': errorMessage !== ''}\">\n <ng-container matColumnDef=\"status\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\" matTooltip=\"Status\"></th>\n <td *matCellDef=\"let invoice\" mat-cell>\n <span *ngIf=\"invoice?.status === 'received'\" class=\"dot green\" matTooltip=\"Received\" matTooltipPosition=\"right\" [ngClass]=\"{'mr-0': screenSize === screenSizeEnum.XS}\"></span>\n <span *ngIf=\"invoice?.status === 'unpaid'\" class=\"dot yellow\" matTooltip=\"Unpaid\" matTooltipPosition=\"right\" [ngClass]=\"{'mr-0': screenSize === screenSizeEnum.XS}\"></span>\n <span *ngIf=\"!invoice?.status || invoice?.status === 'expired' || invoice?.status === 'unknown'\" class=\"dot red\" matTooltip=\"Expired/Unknown\" matTooltipPosition=\"right\" [ngClass]=\"{'mr-0': screenSize === screenSizeEnum.XS}\"></span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"timestamp\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Date Created</th>\n <td *matCellDef=\"let invoice\" mat-cell>{{(invoice?.timestamp * 1000) | date:'dd/MMM/y HH:mm'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"expiresAt\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Date Expiry</th>\n <td *matCellDef=\"let invoice\" mat-cell>{{((invoice?.expiresAt * 1000) | date:'dd/MMM/y HH:mm') || '-'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"receivedAt\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Date Settled</th>\n <td *matCellDef=\"let invoice\" mat-cell>{{((invoice?.receivedAt * 1000) | date:'dd/MMM/y HH:mm') || '-'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"nodeId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Node ID</th>\n <td *matCellDef=\"let invoice\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{invoice?.nodeId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"description\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Description</th>\n <td *matCellDef=\"let invoice\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{invoice?.description}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"paymentHash\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Payment Hash</th>\n <td *matCellDef=\"let invoice\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{invoice?.paymentHash}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"amount\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Amount (Sats)</th>\n <td *matCellDef=\"let invoice\" mat-cell>\n <span fxLayoutAlign=\"end center\">{{invoice?.amount ? (invoice?.amount | number:'1.0-0') : '-'}}</span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"amountSettled\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\" class=\"p1-3\"> Amount Settled (Sats)</th>\n <td *matCellDef=\"let invoice\" mat-cell>\n <span fxLayoutAlign=\"end center\">{{invoice?.amountSettled ? (invoice?.amountSettled | number:'1.0-0') : '-'}}</span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onDownloadCSV()\">Download CSV</mat-option>\n </mat-select>\n </div>\n </th>\n <td *matCellDef=\"let invoice\" mat-cell fxLayoutAlign=\"end center\">\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"4\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onInvoiceClick(invoice)\">View Info</mat-option>\n <mat-option (click)=\"onRefreshInvoice(invoice)\">Refresh</mat-option>\n </mat-select>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"no_invoice\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!invoices?.data || invoices?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No invoice available.</p>\n <p *ngIf=\"(!invoices?.data || invoices?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting invoices...</p>\n <p *ngIf=\"(!invoices?.data || invoices?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_invoice']\" mat-footer-row [ngClass]=\"{'display-none': invoices?.data && invoices?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div>\n <mat-paginator class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild, Input, AfterViewInit } from '@angular/core';\nimport { DecimalPipe, DatePipe } from '@angular/common';\nimport { Subject } from 'rxjs';\nimport { filter, takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { Actions } from '@ngrx/effects';\nimport { faHistory } from '@fortawesome/free-solid-svg-icons';\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\n\nimport { 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';\nimport { SelNodeChild } from '../../../shared/models/RTLconfig';\nimport { GetInfo, Invoice } from '../../../shared/models/eclModels';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { CommonService } from '../../../shared/services/common.service';\n\nimport { ECLCreateInvoiceComponent } from '../create-invoice-modal/create-invoice.component';\nimport { ECLInvoiceInformationComponent } from '../invoice-information-modal/invoice-information.component';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { openAlert } from '../../../store/rtl.actions';\nimport { createInvoice, invoiceLookup } from '../../store/ecl.actions';\nimport { eclNodeInformation, eclNodeSettings, eclPageSettings, invoices } from '../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../shared/pipes/app.pipe';\n\n@Component({\n selector: 'rtl-ecl-lightning-invoices',\n templateUrl: './lightning-invoices.component.html',\n styleUrls: ['./lightning-invoices.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Invoices') }\n ]\n})\nexport class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnDestroy {\n\n @Input() calledFrom = 'transactions'; // Transactions/home\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;\n faHistory = faHistory;\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterBy = 'all';\n public colWidth = '20rem';\n public PAGE_ID = 'transactions';\n public tableSetting: TableSetting = { tableId: 'invoices', recordsPerPage: PAGE_SIZE, sortBy: 'expiresAt', sortOrder: SortOrderEnum.DESCENDING };\n public selNode: SelNodeChild | null = {};\n public newlyAddedInvoiceMemo: string | null = '';\n public newlyAddedInvoiceValue: number | null = 0;\n public description: string | null = '';\n public expiry: number | null;\n public invoiceValue: number | null = null;\n public invoiceValueHint = '';\n public displayedColumns: any[] = [];\n public invoicePaymentReq = '';\n public invoices: any = new MatTableDataSource([]);\n public invoiceJSONArr: Invoice[] = [];\n public information: GetInfo = {};\n public selFilter = '';\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private datePipe: DatePipe, private actions: Actions, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((nodeSettings: SelNodeChild | null) => {\n this.selNode = nodeSettings;\n });\n this.store.select(eclNodeInformation).pipe(takeUntil(this.unSubs[1])).\n subscribe((nodeInfo: any) => {\n this.information = <GetInfo>nodeInfo;\n });\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[2])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.unshift('status');\n this.displayedColumns.push('actions');\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n this.store.select(invoices).pipe(takeUntil(this.unSubs[3])).\n subscribe((invoicesSelector: { invoices: Invoice[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = invoicesSelector.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n this.invoiceJSONArr = (invoicesSelector.invoices && invoicesSelector.invoices.length > 0) ? invoicesSelector.invoices : [];\n if (this.invoiceJSONArr && this.invoiceJSONArr.length > 0 && this.sort && this.paginator && this.displayedColumns.length > 0) {\n this.loadInvoicesTable(this.invoiceJSONArr);\n }\n this.logger.info(invoicesSelector);\n });\n this.actions.pipe(takeUntil(this.unSubs[4]), filter((action) => (action.type === ECLActions.SET_LOOKUP_ECL || action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL))).\n subscribe((resLookup: any) => {\n if (resLookup.type === ECLActions.SET_LOOKUP_ECL) {\n if (this.invoiceJSONArr.length > 0 && this.sort && this.paginator && resLookup.payload) {\n this.updateInvoicesData(JSON.parse(JSON.stringify(resLookup.payload)));\n this.loadInvoicesTable(this.invoiceJSONArr);\n }\n }\n });\n }\n\n ngAfterViewInit() {\n if (this.invoiceJSONArr && this.invoiceJSONArr.length > 0 && this.sort && this.paginator && this.displayedColumns.length > 0) {\n this.loadInvoicesTable(this.invoiceJSONArr);\n }\n }\n\n openCreateInvoiceModal() {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n pageSize: this.pageSize,\n component: ECLCreateInvoiceComponent\n }\n }\n }));\n }\n\n onAddInvoice(form: any): boolean | void {\n if (!this.description) {\n return true;\n }\n const expiryInSecs = (this.expiry ? this.expiry : 3600);\n this.newlyAddedInvoiceMemo = 'ulbl' + Math.random().toString(36).slice(2) + Date.now();\n this.newlyAddedInvoiceValue = this.invoiceValue;\n let invoicePayload: any = null;\n if (this.invoiceValue) {\n invoicePayload = { description: this.description, expireIn: expiryInSecs, amountMsat: this.invoiceValue * 1000 };\n } else {\n invoicePayload = { description: this.description, expireIn: expiryInSecs };\n }\n this.store.dispatch(createInvoice({ payload: invoicePayload }));\n this.resetData();\n }\n\n onInvoiceClick(selInvoice: Invoice) {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n invoice: selInvoice,\n newlyAdded: false,\n component: ECLInvoiceInformationComponent\n }\n }\n }));\n }\n\n onRefreshInvoice(selInvoice: Invoice) {\n this.store.dispatch(invoiceLookup({ payload: selInvoice.paymentHash! }));\n }\n\n updateInvoicesData(newInvoice: Invoice) {\n this.invoiceJSONArr = this.invoiceJSONArr?.map((invoice) => ((invoice.paymentHash === newInvoice.paymentHash) ? newInvoice : invoice));\n }\n\n applyFilter() {\n this.invoices.filter = this.selFilter.trim().toLowerCase();\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column, '_') : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.invoices.filterPredicate = (rowData: Invoice, fltr: string) => {\n let rowToFilter = '';\n switch (this.selFilterBy) {\n case 'all':\n rowToFilter = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp * 1000), 'dd/MMM/y HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();\n break;\n\n case 'status':\n rowToFilter = !rowData?.status || rowData?.status === 'expired' || rowData?.status === 'unknown' ? 'expired/unknown' : rowData.status?.toLowerCase();\n break;\n\n case 'timestamp':\n case 'expiresAt':\n case 'receivedAt':\n rowToFilter = this.datePipe.transform(new Date((rowData[this.selFilterBy] || 0) * 1000), 'dd/MMM/y HH:mm')?.toLowerCase() || '';\n break;\n\n case 'amount':\n case 'amountSettled':\n rowToFilter = rowData[this.selFilterBy]?.toString() || '-';\n break;\n\n default:\n rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();\n break;\n }\n return this.selFilterBy === 'status' ? rowToFilter.indexOf(fltr) === 0 : rowToFilter.includes(fltr);\n };\n }\n\n loadInvoicesTable(invs: Invoice[]) {\n this.invoices = invs ? new MatTableDataSource<Invoice>([...invs]) : new MatTableDataSource<Invoice>([]);\n this.invoices.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);\n this.invoices.sort = this.sort;\n this.invoices.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.invoices.paginator = this.paginator;\n this.setFilterPredicate();\n this.applyFilter();\n }\n\n resetData() {\n this.description = '';\n this.invoiceValue = null;\n this.expiry = null;\n this.invoiceValueHint = '';\n }\n\n onInvoiceValueChange() {\n if (this.selNode && this.selNode.fiatConversion && this.invoiceValue && this.invoiceValue > 99) {\n this.invoiceValueHint = '';\n this.commonService.convertCurrency(this.invoiceValue, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).\n pipe(takeUntil(this.unSubs[5])).\n subscribe({\n next: (data) => {\n this.invoiceValueHint = '= ' + data.symbol + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;\n }, error: (err) => {\n this.invoiceValueHint = 'Conversion Error: ' + err;\n }\n });\n }\n }\n\n onDownloadCSV() {\n if (this.invoices.data && this.invoices.data.length > 0) {\n this.commonService.downloadFile(this.invoices.data, 'Invoices');\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div *ngIf=\"selNode?.userPersona === userPersonaEnum.OPERATOR; else merchantDashboard\"fxLayout=\"column\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start start\" class=\"page-title-container mb-2\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"apiCallStatusNodeInfo.status === apiCallStatusEnum.ERROR ? faFrown : faSmile\"></fa-icon>\n <span class=\"page-title\">{{apiCallStatusNodeInfo.status === apiCallStatusEnum.COMPLETED ? 'Welcome ' + information.alias + '! Your node is up and running.' : apiCallStatusNodeInfo.status === apiCallStatusEnum.INITIATED ? 'Wait! Getting your node information...' : 'Error! Please check the server connection.'}}</span>\n </div>\n <mat-grid-list cols=\"10\" gutterSize=\"20px\" [rowHeight]=\"operatorCardHeight\">\n <mat-grid-tile *ngFor=\"let card of operatorCards\" fxFlex=\"100\" fxLayout=\"column\" fxLayoutAlign=\"start stretch\" [colspan]=\"card.cols\" [rowspan]=\"card.rows\">\n <mat-card fxFlex=\"100\" fxLayout=\"column\" fxLayoutAlign=\"start stretch\" class=\"h-100 dashboard-card\">\n <mat-card-header>\n <mat-card-title fxLayoutAlign=\"space-between center\">\n <div>\n <fa-icon class=\"mr-1\" [icon]=\"card.icon\"></fa-icon>\n <span>{{card.title}}</span>\n </div>\n <div>\n <button *ngIf=\"card.links[0]\" mat-icon-button class=\"more-button\" aria-label=\"Toggle menu\"\n [matMenuTriggerFor]=\"menuOperator\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menuOperator=\"matMenu\" class=\"dashboard-vert-menu\" xPosition=\"before\">\n <button *ngFor=\"let goToOption of card.goToOptions; index as i\" mat-menu-item (click)=\"onNavigateTo(card.links[i])\">{{goToOption}}</button>\n <button *ngIf=\"card.id === 'capacity'\" mat-menu-item (click)=\"onsortChannelsBy()\">Sort By\n {{sortField === 'Balance Score' ? 'Capacity' : 'Balance Score'}}</button>\n </mat-menu>\n </div>\n </mat-card-title>\n </mat-card-header>\n <mat-card-content fxLayout=\"column\" fxFlex=\"{{card.id === 'capacity' ? 90 : 70}}\"\n [ngClass]=\"{'dashboard-card-content': true, \n 'error-border': (card.id === 'node' && apiCallStatusNodeInfo.status === apiCallStatusEnum.ERROR) ||\n (card.id === 'balance' && (apiCallStatusAllChannels.status === apiCallStatusEnum.ERROR || apiCallStatusOCBal.status === apiCallStatusEnum.ERROR)) ||\n ((card.id === 'capacity' || card.id === 'status') && apiCallStatusAllChannels.status === apiCallStatusEnum.ERROR) ||\n (card.id === 'fee' && apiCallStatusFees.status === apiCallStatusEnum.ERROR)}\">\n <mat-progress-bar *ngIf=\"(card.id === 'node' && apiCallStatusNodeInfo.status === apiCallStatusEnum.INITIATED) ||\n (card.id === 'balance' && (apiCallStatusAllChannels.status === apiCallStatusEnum.INITIATED || apiCallStatusOCBal.status === apiCallStatusEnum.INITIATED)) ||\n ((card.id === 'capacity' || card.id === 'status') && apiCallStatusAllChannels.status === apiCallStatusEnum.INITIATED) ||\n (card.id === 'fee' && apiCallStatusFees.status === apiCallStatusEnum.INITIATED)\"\n mode=\"indeterminate\"\n ></mat-progress-bar>\n <div fxLayout=\"column\" fxFlex=\"100\" [ngSwitch]=\"card.id\">\n <rtl-ecl-node-info *ngSwitchCase=\"'node'\" fxFlex=\"100\" [information]=\"information\" [showColorFieldSeparately]=\"false\"></rtl-ecl-node-info>\n <rtl-ecl-balances-info *ngSwitchCase=\"'balance'\" fxFlex=\"100\" [balances]=\"balances\" [errorMessage]=\"errorMessages[2] + ' ' + errorMessages[3]\"></rtl-ecl-balances-info>\n <rtl-ecl-channel-capacity-info *ngSwitchCase=\"'capacity'\" fxFlex=\"100\" [sortBy]=\"sortField\" [channelBalances]=\"channelBalances\" [allChannels]=\"allChannelsCapacity\" [errorMessage]=\"errorMessages[2]\"></rtl-ecl-channel-capacity-info>\n <rtl-ecl-fee-info *ngSwitchCase=\"'fee'\" fxFlex=\"100\" [fees]=\"fees\" [errorMessage]=\"errorMessages[1]\"></rtl-ecl-fee-info>\n <rtl-ecl-channel-status-info *ngSwitchCase=\"'status'\" fxFlex=\"100\" [channelsStatus]=\"channelsStatus\" [errorMessage]=\"errorMessages[2]\"></rtl-ecl-channel-status-info>\n <h3 *ngSwitchDefault>Error! Unable to find information!</h3>\n </div>\n </mat-card-content>\n </mat-card>\n </mat-grid-tile>\n </mat-grid-list>\n</div>\n<ng-template #merchantDashboard>\n <div fxLayout=\"row\" fxLayoutAlign=\"start end\" class=\"page-title-container mb-2\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faSmile\"></fa-icon>\n <span class=\"page-title\">Welcome {{information.alias}}! Your node is up and running.</span>\n </div>\n <mat-grid-list cols=\"6\" gutterSize=\"20px\" [rowHeight]=\"merchantCardHeight\">\n <mat-grid-tile *ngFor=\"let card of merchantCards\" fxFlex=\"100\" fxLayout=\"column\" fxLayoutAlign=\"start stretch\" [colspan]=\"card.cols\" [rowspan]=\"card.rows\">\n <mat-card fxFlex=\"100\" fxLayout=\"column\" fxLayoutAlign=\"start stretch\" class=\"h-100 dashboard-card\" [ngClass]=\"{'p-0': card.id === 'transactions'}\">\n <mat-card-header *ngIf=\"card.id !== 'transactions'\">\n <mat-card-title fxLayoutAlign=\"space-between center\">\n <div>\n <fa-icon class=\"mr-1\" [icon]=\"card.icon\"></fa-icon>\n <span>{{card.title}}</span>\n </div>\n <div>\n <button *ngIf=\"card.links[0]\" mat-icon-button class=\"more-button\" aria-label=\"Toggle menu\"\n [matMenuTriggerFor]=\"menuMerchant\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menuMerchant=\"matMenu\" class=\"dashboard-vert-menu\" xPosition=\"before\">\n <button *ngFor=\"let goToOption of card.goToOptions; index as i\" mat-menu-item (click)=\"onNavigateTo(card.links[i])\">{{goToOption}}</button>\n </mat-menu>\n </div>\n </mat-card-title>\n </mat-card-header>\n <mat-card-content fxLayout=\"column\" fxLayoutAlign=\"start stretch\" fxFlex=\"{{card.id === 'transactions' ? 100 : card.id === 'balance' ? 70: 90}}\"\n [ngClass]=\"{'dashboard-card-content': true, \n 'error-border': (card.id === 'node' && apiCallStatusNodeInfo.status === apiCallStatusEnum.ERROR) ||\n (card.id === 'balance' && (apiCallStatusAllChannels.status === apiCallStatusEnum.ERROR || apiCallStatusOCBal.status === apiCallStatusEnum.ERROR)) ||\n ((card.id === 'inboundLiq' || card.id === 'outboundLiq') && apiCallStatusAllChannels.status === apiCallStatusEnum.ERROR)}\">\n <mat-progress-bar *ngIf=\"(card.id === 'node' && apiCallStatusNodeInfo.status === apiCallStatusEnum.INITIATED) ||\n (card.id === 'balance' && (apiCallStatusAllChannels.status === apiCallStatusEnum.INITIATED || apiCallStatusOCBal.status === apiCallStatusEnum.INITIATED)) ||\n ((card.id === 'inboundLiq' || card.id === 'outboundLiq') && apiCallStatusAllChannels.status === apiCallStatusEnum.INITIATED)\"\n mode=\"indeterminate\"\n ></mat-progress-bar>\n <div fxLayout=\"column\" fxFlex=\"100\" [ngSwitch]=\"card.id\">\n <rtl-ecl-node-info *ngSwitchCase=\"'node'\" fxFlex=\"100\" [information]=\"information\"></rtl-ecl-node-info>\n <rtl-ecl-balances-info *ngSwitchCase=\"'balance'\" fxFlex=\"100\" [balances]=\"balances\" [errorMessage]=\"errorMessages[2] + ' ' + errorMessages[3]\"></rtl-ecl-balances-info>\n <rtl-ecl-channel-liquidity-info *ngSwitchCase=\"'inboundLiq'\" fxFlex=\"100\" [direction]=\"'In'\" [totalLiquidity]=\"totalInboundLiquidity\" [allChannels]=\"allInboundChannels\" [errorMessage]=\"errorMessages[2]\"></rtl-ecl-channel-liquidity-info>\n <rtl-ecl-channel-liquidity-info *ngSwitchCase=\"'outboundLiq'\" fxFlex=\"100\" [direction]=\"'Out'\" [totalLiquidity]=\"totalOutboundLiquidity\" [allChannels]=\"allOutboundChannels\" [errorMessage]=\"errorMessages[2]\"></rtl-ecl-channel-liquidity-info>\n <span *ngSwitchCase=\"'transactions'\" fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between start\">\n <mat-tab-group fxLayout=\"column\" class=\"w-100 dashboard-tabs-group\">\n <mat-tab label=\"Receive\">\n <rtl-ecl-lightning-invoices class=\"h-100\" [calledFrom]=\"'home'\"></rtl-ecl-lightning-invoices>\n </mat-tab>\n <mat-tab label=\"Pay\">\n <rtl-ecl-lightning-payments [calledFrom]=\"'home'\"></rtl-ecl-lightning-payments>\n </mat-tab>\n <mat-tab [disabled]=\"true\">\n <ng-template mat-tab-label>\n <button mat-icon-button class=\"more-button\" aria-label=\"Toggle menu\" [matMenuTriggerFor]=\"menuTransactions\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <mat-menu #menuTransactions=\"matMenu\" class=\"dashboard-vert-menu\" xPosition=\"before\">\n <button *ngFor=\"let goToOption of card.goToOptions; index as i\" mat-menu-item (click)=\"onNavigateTo(card.links[i])\">{{goToOption}}</button>\n </mat-menu>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n </span>\n <h3 *ngSwitchDefault>Error! Unable to find information!</h3>\n </div>\n </mat-card-content>\n </mat-card>\n </mat-grid-tile>\n </mat-grid-list>\n</ng-template>\n","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil, withLatestFrom } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { faSmile, faFrown } from '@fortawesome/free-regular-svg-icons';\nimport { faAngleDoubleDown, faAngleDoubleUp, faChartPie, faBolt, faServer, faNetworkWired } from '@fortawesome/free-solid-svg-icons';\n\nimport { LoggerService } from '../../shared/services/logger.service';\nimport { CommonService } from '../../shared/services/common.service';\nimport { UserPersonaEnum, ScreenSizeEnum, APICallStatusEnum } from '../../shared/services/consts-enums-functions';\nimport { GetInfo, Channel, Fees, OnChainBalance, ChannelsStatus, LightningBalance } from '../../shared/models/eclModels';\nimport { ApiCallStatusPayload } from '../../shared/models/apiCallsPayload';\nimport { SelNodeChild } from '../../shared/models/RTLconfig';\n\nimport { RTLState } from '../../store/rtl.state';\nimport { allChannelsInfo, eclNodeSettings, fees, nodeInfoStatus, onchainBalance } from '../store/ecl.selector';\n\nexport interface Tile {\n id: string;\n title: string;\n cols: number;\n rows: number;\n goToOptions?: string[];\n links?: string[];\n icon?: any;\n}\n\n@Component({\n selector: 'rtl-ecl-home',\n templateUrl: './home.component.html',\n styleUrls: ['./home.component.scss']\n})\nexport class ECLHomeComponent implements OnInit, OnDestroy {\n\n public faSmile = faSmile;\n public faFrown = faFrown;\n public faAngleDoubleDown = faAngleDoubleDown;\n public faAngleDoubleUp = faAngleDoubleUp;\n public faChartPie = faChartPie;\n public faBolt = faBolt;\n public faServer = faServer;\n public faNetworkWired = faNetworkWired;\n public userPersonaEnum = UserPersonaEnum;\n public channelBalances = { localBalance: 0, remoteBalance: 0, balancedness: 0 };\n public selNode: SelNodeChild | null = {};\n public fees: Fees;\n public information: GetInfo = {};\n public channels: Channel[] = [];\n public onchainBalance: OnChainBalance = {};\n public balances = { onchain: -1, lightning: -1, total: 0 };\n public channelsStatus: ChannelsStatus = {};\n public allChannelsCapacity: Channel[] = [];\n public allInboundChannels: Channel[] = [];\n public allOutboundChannels: Channel[] = [];\n public totalInboundLiquidity = 0;\n public totalOutboundLiquidity = 0;\n public operatorCards: Tile[] = [];\n public merchantCards: Tile[] = [];\n public screenSize = '';\n public operatorCardHeight = '405px';\n public merchantCardHeight = '65px';\n public sortField = 'Balance Score';\n public errorMessages = ['', '', '', ''];\n public apiCallStatusNodeInfo: ApiCallStatusPayload = { status: APICallStatusEnum.COMPLETED };\n public apiCallStatusFees: ApiCallStatusPayload = { status: APICallStatusEnum.COMPLETED };\n public apiCallStatusOCBal: ApiCallStatusPayload = { status: APICallStatusEnum.COMPLETED };\n public apiCallStatusAllChannels: ApiCallStatusPayload = { status: APICallStatusEnum.COMPLETED };\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private router: Router) {\n this.screenSize = this.commonService.getScreenSize();\n if (this.screenSize === ScreenSizeEnum.XS) {\n this.operatorCards = [\n { id: 'node', goToOptions: [], links: [], icon: this.faServer, title: 'Node Information', cols: 10, rows: 1 },\n { id: 'balance', goToOptions: ['On-Chain'], links: ['onchain'], icon: this.faChartPie, title: 'Balances', cols: 10, rows: 1 },\n { id: 'fee', goToOptions: ['Routing', 'Fees Summary'], links: ['routing', 'reports'], icon: this.faBolt, title: 'Routing Fee', cols: 10, rows: 1 },\n { id: 'status', goToOptions: ['Channels', 'Inactive Channels'], links: ['connections', 'connections/channels/inactive'], icon: this.faNetworkWired, title: 'Channels', cols: 10, rows: 1 },\n { id: 'capacity', goToOptions: ['Channels'], links: ['connections'], icon: this.faNetworkWired, title: 'Channels Capacity', cols: 10, rows: 2 }\n ];\n this.merchantCards = [\n { id: 'balance', goToOptions: ['On-Chain'], links: ['onchain'], icon: this.faChartPie, title: 'Balances', cols: 6, rows: 4 },\n { id: 'transactions', goToOptions: ['Transactions', 'Transactions Summary'], links: ['transactions', 'reports/transactions'], title: '', cols: 6, rows: 4 },\n { id: 'inboundLiq', goToOptions: ['Channels'], links: ['connections'], icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 6, rows: 8 },\n { id: 'outboundLiq', goToOptions: ['Channels'], links: ['connections'], icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 6, rows: 8 }\n ];\n } else if (this.screenSize === ScreenSizeEnum.SM || this.screenSize === ScreenSizeEnum.MD) {\n this.operatorCards = [\n { id: 'node', goToOptions: [], links: [], icon: this.faServer, title: 'Node Information', cols: 5, rows: 1 },\n { id: 'balance', goToOptions: ['On-Chain'], links: ['onchain'], icon: this.faChartPie, title: 'Balances', cols: 5, rows: 1 },\n { id: 'fee', goToOptions: ['Routing', 'Fees Summary'], links: ['routing', 'reports'], icon: this.faBolt, title: 'Routing Fee', cols: 5, rows: 1 },\n { id: 'status', goToOptions: ['Channels', 'Inactive Channels'], links: ['connections', 'connections/channels/inactive'], icon: this.faNetworkWired, title: 'Channels', cols: 5, rows: 1 },\n { id: 'capacity', goToOptions: ['Channels'], links: ['connections'], icon: this.faNetworkWired, title: 'Channels Capacity', cols: 10, rows: 2 }\n ];\n this.merchantCards = [\n { id: 'balance', goToOptions: ['On-Chain'], links: ['onchain'], icon: this.faChartPie, title: 'Balances', cols: 3, rows: 4 },\n { id: 'transactions', goToOptions: ['Transactions', 'Transactions Summary'], links: ['transactions', 'reports/transactions'], title: '', cols: 3, rows: 4 },\n { id: 'inboundLiq', goToOptions: ['Channels'], links: ['connections'], icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 3, rows: 8 },\n { id: 'outboundLiq', goToOptions: ['Channels'], links: ['connections'], icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 3, rows: 8 }\n ];\n } else {\n this.operatorCards = [\n { id: 'node', goToOptions: [], links: [], icon: this.faServer, title: 'Node Information', cols: 3, rows: 1 },\n { id: 'balance', goToOptions: ['On-Chain'], links: ['onchain'], icon: this.faChartPie, title: 'Balances', cols: 3, rows: 1 },\n { id: 'capacity', goToOptions: ['Channels'], links: ['connections'], icon: this.faNetworkWired, title: 'Channels Capacity', cols: 4, rows: 2 },\n { id: 'fee', goToOptions: ['Routing', 'Fees Summary'], links: ['routing', 'reports'], icon: this.faBolt, title: 'Routing Fee', cols: 3, rows: 1 },\n { id: 'status', goToOptions: ['Channels', 'Inactive Channels'], links: ['connections', 'connections/channels/inactive'], icon: this.faNetworkWired, title: 'Channels', cols: 3, rows: 1 }\n ];\n this.merchantCards = [\n { id: 'balance', goToOptions: ['On-Chain'], links: ['onchain'], icon: this.faChartPie, title: 'Balances', cols: 2, rows: 5 },\n { id: 'inboundLiq', goToOptions: ['Channels'], links: ['connections'], icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 2, rows: 10 },\n { id: 'outboundLiq', goToOptions: ['Channels'], links: ['connections'], icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 2, rows: 10 },\n { id: 'transactions', goToOptions: ['Transactions', 'Transactions Summary'], links: ['transactions', 'reports/transactions'], title: '', cols: 2, rows: 5 }\n ];\n }\n }\n\n ngOnInit() {\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((nodeSettings) => {\n this.selNode = nodeSettings;\n });\n this.store.select(nodeInfoStatus).pipe(takeUntil(this.unSubs[1])).\n subscribe((selNodeInfoStatusSelector: { information: GetInfo, apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessages[0] = '';\n this.apiCallStatusNodeInfo = selNodeInfoStatusSelector.apiCallStatus;\n if (this.apiCallStatusNodeInfo.status === APICallStatusEnum.ERROR) {\n this.errorMessages[0] = (typeof (this.apiCallStatusNodeInfo.message) === 'object') ? JSON.stringify(this.apiCallStatusNodeInfo.message) : this.apiCallStatusNodeInfo.message ? this.apiCallStatusNodeInfo.message : '';\n }\n this.information = selNodeInfoStatusSelector.information;\n });\n\n this.store.select(fees).pipe(takeUntil(this.unSubs[2])).\n subscribe((feesSelector: { fees: Fees, apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessages[1] = '';\n this.apiCallStatusFees = feesSelector.apiCallStatus;\n if (this.apiCallStatusFees.status === APICallStatusEnum.ERROR) {\n this.errorMessages[1] = (typeof (this.apiCallStatusFees.message) === 'object') ? JSON.stringify(this.apiCallStatusFees.message) : this.apiCallStatusFees.message ? this.apiCallStatusFees.message : '';\n }\n this.fees = feesSelector.fees;\n });\n this.store.select(allChannelsInfo).pipe(takeUntil(this.unSubs[3]),\n withLatestFrom(this.store.select(onchainBalance))).\n subscribe(([allChannelsSelector, oCBalanceSelector]: [({ activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], lightningBalance: LightningBalance, channelsStatus: ChannelsStatus, apiCallStatus: ApiCallStatusPayload }),\n ({ onchainBalance: OnChainBalance, apiCallStatus: ApiCallStatusPayload })]) => {\n this.errorMessages[2] = '';\n this.errorMessages[3] = '';\n this.apiCallStatusAllChannels = allChannelsSelector.apiCallStatus;\n this.apiCallStatusOCBal = oCBalanceSelector.apiCallStatus;\n if (this.apiCallStatusAllChannels.status === APICallStatusEnum.ERROR) {\n this.errorMessages[2] = (typeof (this.apiCallStatusAllChannels.message) === 'object') ? JSON.stringify(this.apiCallStatusAllChannels.message) : this.apiCallStatusAllChannels.message ? this.apiCallStatusAllChannels.message : '';\n }\n if (this.apiCallStatusOCBal.status === APICallStatusEnum.ERROR) {\n this.errorMessages[3] = (typeof (this.apiCallStatusOCBal.message) === 'object') ? JSON.stringify(this.apiCallStatusOCBal.message) : this.apiCallStatusOCBal.message ? this.apiCallStatusOCBal.message : '';\n }\n this.channels = allChannelsSelector.activeChannels;\n this.onchainBalance = oCBalanceSelector.onchainBalance;\n this.balances.onchain = this.onchainBalance.total || 0;\n this.balances.lightning = allChannelsSelector.lightningBalance.localBalance;\n this.balances.total = this.balances.lightning + this.balances.onchain;\n this.balances = Object.assign({}, this.balances);\n const local = (allChannelsSelector.lightningBalance.localBalance) ? +allChannelsSelector.lightningBalance.localBalance : 0;\n const remote = (allChannelsSelector.lightningBalance.remoteBalance) ? +allChannelsSelector.lightningBalance.remoteBalance : 0;\n const total = local + remote;\n this.channelBalances = { localBalance: local, remoteBalance: remote, balancedness: +(1 - Math.abs((local - remote) / total)).toFixed(3) };\n this.channelsStatus = allChannelsSelector.channelsStatus;\n this.totalInboundLiquidity = 0;\n this.totalOutboundLiquidity = 0;\n this.allChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels, 'balancedness')));\n this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels?.filter((channel: Channel) => (channel.toRemote || 0) > 0), 'toRemote')));\n this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels?.filter((channel: Channel) => (channel.toLocal || 0) > 0), 'toLocal')));\n this.channels.forEach((channel: Channel) => {\n this.totalInboundLiquidity = this.totalInboundLiquidity + Math.ceil(channel.toRemote || 0);\n this.totalOutboundLiquidity = this.totalOutboundLiquidity + Math.floor(channel.toLocal || 0);\n });\n this.logger.info(allChannelsSelector);\n });\n }\n\n onNavigateTo(link: string) {\n this.router.navigateByUrl('/ecl/' + link);\n }\n\n onsortChannelsBy() {\n if (this.sortField === 'Balance Score') {\n this.sortField = 'Capacity';\n this.allChannelsCapacity = this.channels.sort((a: Channel, b: Channel) => {\n const x = +(a.toLocal || 0) + +(a.toRemote || 0);\n const y = +(b.toLocal || 0) + +(b.toRemote || 0);\n return ((x > y) ? -1 : ((x < y) ? 1 : 0));\n });\n } else {\n this.sortField = 'Balance Score';\n this.allChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels, 'balancedness')));\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <mat-card-header fxLayout=\"row\" fxLayoutAlign=\"space-between center\" class=\"modal-info-header\">\n <div fxFlex=\"95\" fxLayoutAlign=\"start start\">\n <span class=\"page-title\">Send Payment</span>\n </div>\n <button tabindex=\"8\" fxFlex=\"5\" fxLayoutAlign=\"center\" class=\"btn-close-x p-0\" default mat-button [mat-dialog-close]=\"false\">X</button>\n </mat-card-header>\n <mat-card-content class=\"padding-gap-x-large\">\n <form #form=\"ngForm\" fxLayout=\"row wrap\" fxFlex=\"100\" fxLayoutAlign=\"space-between start\" class=\"overflow-x-hidden\" (submit)=\"onSendFunds()\" (reset)=\"resetData()\">\n <mat-form-field fxFlex=\"55\">\n <input #addrs=\"ngModel\" matInput autoFocus placeholder=\"Bitcoin Address\" tabindex=\"1\" name=\"addr\" required [(ngModel)]=\"transaction.address\">\n <mat-error *ngIf=\"!transaction.address\">Bitcoin address is required.</mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"30\">\n <input #amnt=\"ngModel\" matInput placeholder=\"Amount\" name=\"amt\" type=\"number\" tabindex=\"2\" required [step]=\"100\" [min]=\"0\" [(ngModel)]=\"transaction.amount\">\n <span matSuffix>{{selAmountUnit}} </span>\n <mat-error *ngIf=\"!transaction.amount\">{{amountError}}</mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"10\" fxLayoutAlign=\"start end\">\n <mat-select tabindex=\"3\" required name=\"amountUnit\" [value]=\"selAmountUnit\" (selectionChange)=\"onAmountUnitChange($event)\">\n <mat-option *ngFor=\"let amountUnit of amountUnits\" [value]=\"amountUnit\">{{amountUnit}}</mat-option>\n </mat-select>\n </mat-form-field>\n <div fxFlex=\"60\" fxLayoutAlign=\"space-between stretch\" fxLayout=\"row wrap\">\n <mat-form-field fxFlex=\"48\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <input #blocks=\"ngModel\" matInput placeholder=\"Target Confirmation Blocks\" type=\"number\" name=\"blocks\" tabindex=\"8\" required=\"true\" [step]=\"1\" [min]=\"0\" [(ngModel)]=\"transaction.blocks\">\n <mat-error *ngIf=\"!transaction.blocks\">Target Confirmation Blocks is required.</mat-error>\n </mat-form-field>\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start stretch\"></div>\n <div *ngIf=\"sendFundError !== ''\" fxFlex=\"100\" class=\"alert alert-danger mt-1\">\n <fa-icon class=\"mr-1 alert-icon\" [icon]=\"faExclamationTriangle\"></fa-icon>\n <span *ngIf=\"sendFundError !== ''\">{{sendFundError}}</span>\n </div>\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"end center\">\n <button class=\"mr-1\" mat-button color=\"primary\" tabindex=\"7\" type=\"reset\">Clear Fields</button>\n <button mat-button color=\"primary\" type=\"submit\" tabindex=\"8\">Send Funds</button>\n </div>\n </form>\n </mat-card-content>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';\nimport { DecimalPipe } from '@angular/common';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { Actions } from '@ngrx/effects';\nimport { MatDialogRef } from '@angular/material/dialog';\nimport { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';\n\nimport { SelNodeChild } from '../../../shared/models/RTLconfig';\nimport { GetInfo, OnChainBalance, SendPaymentOnChain } from '../../../shared/models/eclModels';\nimport { CURRENCY_UNITS, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, ADDRESS_TYPES, APICallStatusEnum, ECLActions } from '../../../shared/services/consts-enums-functions';\nimport { CommonService } from '../../../shared/services/common.service';\nimport { LoggerService } from '../../../shared/services/logger.service';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { openSnackBar } from '../../../store/rtl.actions';\nimport { sendOnchainFunds } from '../../store/ecl.actions';\nimport { rootSelectedNode } from '../../../store/rtl.selector';\n\n@Component({\n selector: 'rtl-ecl-on-chain-send-modal',\n templateUrl: './on-chain-send-modal.component.html',\n styleUrls: ['./on-chain-send-modal.component.scss']\n})\nexport class ECLOnChainSendModalComponent implements OnInit, OnDestroy {\n\n @ViewChild('form', { static: true }) form: any;\n public faExclamationTriangle = faExclamationTriangle;\n public selNode: SelNodeChild | null = {};\n public addressTypes = [];\n public selectedAddress = ADDRESS_TYPES[1];\n public blockchainBalance: OnChainBalance = {};\n public information: GetInfo = {};\n public newAddress = '';\n public transaction: SendPaymentOnChain = {};\n public sendFundError = '';\n public fiatConversion = false;\n public amountUnits = CURRENCY_UNITS;\n public selAmountUnit = CURRENCY_UNITS[0];\n public currConvertorRate = {};\n public unitConversionValue = 0;\n public currencyUnitFormats = CURRENCY_UNIT_FORMATS;\n public amountError = 'Amount is Required.';\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(public dialogRef: MatDialogRef<ECLOnChainSendModalComponent>, private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private decimalPipe: DecimalPipe, private actions: Actions) { }\n\n ngOnInit() {\n this.store.select(rootSelectedNode).pipe(takeUntil(this.unSubs[0])).subscribe((selNode) => {\n this.fiatConversion = selNode.settings.fiatConversion;\n this.amountUnits = selNode.settings.currencyUnits;\n this.logger.info(selNode);\n });\n this.actions.pipe(\n takeUntil(this.unSubs[1]),\n filter((action) => action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL || action.type === ECLActions.SEND_ONCHAIN_FUNDS_RES_ECL)\n ).\n subscribe((action: any) => {\n if (action.type === ECLActions.SEND_ONCHAIN_FUNDS_RES_ECL) {\n this.store.dispatch(openSnackBar({ payload: 'Fund Sent Successfully!' }));\n this.dialogRef.close();\n }\n if (action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL && action.payload.status === APICallStatusEnum.ERROR && action.payload.action === 'SendOnchainFunds') {\n this.sendFundError = action.payload.message;\n }\n });\n }\n\n onSendFunds(): boolean | void {\n if (this.invalidValues) {\n return true;\n }\n this.sendFundError = '';\n if (this.transaction.amount && this.selAmountUnit !== CurrencyUnitEnum.SATS) {\n this.commonService.convertCurrency(this.transaction.amount, this.selAmountUnit === this.amountUnits[2] ? CurrencyUnitEnum.OTHER : this.selAmountUnit, CurrencyUnitEnum.SATS, this.amountUnits[2], this.fiatConversion).\n pipe(takeUntil(this.unSubs[2])).\n subscribe({\n next: (data) => {\n this.transaction.amount = parseInt(data[CurrencyUnitEnum.SATS]);\n this.selAmountUnit = CurrencyUnitEnum.SATS;\n this.store.dispatch(sendOnchainFunds({ payload: this.transaction }));\n }, error: (err) => {\n this.selAmountUnit = CurrencyUnitEnum.SATS;\n this.amountError = 'Conversion Error: ' + err;\n }\n });\n } else {\n this.store.dispatch(sendOnchainFunds({ payload: this.transaction }));\n }\n }\n\n get invalidValues(): boolean {\n return (!this.transaction.address || this.transaction.address === '') ||\n ((!this.transaction.amount || this.transaction.amount <= 0)) ||\n (!this.transaction.blocks || this.transaction.blocks <= 0);\n }\n\n resetData() {\n this.sendFundError = '';\n this.transaction = {};\n }\n\n onAmountUnitChange(event: any) {\n const self = this;\n const prevSelectedUnit = (this.selAmountUnit === this.amountUnits[2]) ? CurrencyUnitEnum.OTHER : this.selAmountUnit;\n let currSelectedUnit = event.value === this.amountUnits[2] ? CurrencyUnitEnum.OTHER : event.value;\n if (this.transaction.amount && this.selAmountUnit !== event.value) {\n this.commonService.convertCurrency(this.transaction.amount, prevSelectedUnit, currSelectedUnit, this.amountUnits[2], this.fiatConversion).\n pipe(takeUntil(this.unSubs[3])).\n subscribe({\n next: (data) => {\n this.selAmountUnit = event.value;\n self.transaction.amount = +self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit])!.replace(/,/g, '');\n }, error: (err) => {\n this.amountError = 'Conversion Error: ' + err;\n this.selAmountUnit = prevSelectedUnit;\n currSelectedUnit = prevSelectedUnit;\n }\n });\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"row wrap\" fxLayoutAlign=\"start start\" fxLayout.gt-sm=\"column\" fxFlex=\"100\" fxLayoutAlign.gt-sm=\"start stretch\">\n <div fxLayout=\"column\" fxLayout.gt-xs=\"row wrap\" fxLayoutAlign.gt-xs=\"start center\" fxLayoutAlign=\"start stretch\" class=\"page-sub-title-container\">\n <div fxFlex=\"70\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faHistory\"></fa-icon>\n <span class=\"page-title\">Transaction History</span>\n </div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput name=\"filter\" placeholder=\"Filter\" [(ngModel)]=\"selFilter\" (input)=\"applyFilter()\" (keyup)=\"applyFilter()\">\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"row\" fxLayoutAlign=\"start start\">\n <div fxLayout=\"column\" fxLayoutAlign=\"start end\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #table mat-table fxFlex=\"100\" matSort [dataSource]=\"listTransactions\"\n [ngClass]=\"{'error-border': errorMessage !== ''}\">\n <ng-container matColumnDef=\"timestamp\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Date/Time</th>\n <td *matCellDef=\"let transaction\" mat-cell>{{(transaction?.timestamp * 1000) | date:'dd/MMM/y HH:mm'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"address\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Address</th>\n <td *matCellDef=\"let transaction\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{transaction?.address}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"blockHash\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Blockhash</th>\n <td *matCellDef=\"let transaction\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{transaction?.blockHash}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"txid\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Transaction ID</th>\n <td *matCellDef=\"let transaction\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{transaction?.txid}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"amount\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Amount (Sats)</th>\n <td *matCellDef=\"let transaction\" mat-cell>\n <span *ngIf=\"transaction?.amount > 0 || transaction?.amount === 0\" fxLayoutAlign=\"end center\">{{transaction?.amount | number}}</span>\n <span *ngIf=\"transaction?.amount < 0\" fxLayoutAlign=\"end center\" class=\"red\">({{transaction?.amount * -1 | number}})</span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"fees\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Fees (Sats)</th>\n <td *matCellDef=\"let transaction\" mat-cell><span fxLayoutAlign=\"end center\">{{transaction?.fees | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"confirmations\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Confirmations</th>\n <td *matCellDef=\"let transaction\" mat-cell><span fxLayoutAlign=\"end center\">\n {{transaction?.confirmations | number}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onDownloadCSV()\">Download CSV</mat-option>\n </mat-select>\n </div>\n </th>\n <td *matCellDef=\"let transaction\" mat-cell fxLayoutAlign=\"end center\">\n <button mat-stroked-button color=\"primary\" type=\"button\" tabindex=\"4\" class=\"table-actions-button\" (click)=\"onTransactionClick(transaction, $event)\">View Info</button>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"no_transaction\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!listTransactions?.data || listTransactions?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No transaction available.</p>\n <p *ngIf=\"(!listTransactions?.data || listTransactions?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting transactions...</p>\n <p *ngIf=\"(!listTransactions?.data || listTransactions?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_transaction']\" mat-footer-row [ngClass]=\"{'display-none': listTransactions?.data && listTransactions?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n <mat-paginator class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n </div>\n </div>\n</div>","import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { faHistory } from '@fortawesome/free-solid-svg-icons';\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\n\nimport { Transaction } from '../../../shared/models/eclModels';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\nimport { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { CommonService } from '../../../shared/services/common.service';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { openAlert } from '../../../store/rtl.actions';\nimport { fetchTransactions } from '../../store/ecl.actions';\nimport { eclPageSettings, transactions } from '../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../shared/pipes/app.pipe';\n\n@Component({\n selector: 'rtl-ecl-on-chain-transaction-history',\n templateUrl: './on-chain-transaction-history.component.html',\n styleUrls: ['./on-chain-transaction-history.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Transactions') }\n ]\n})\nexport class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy {\n\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;\n public faHistory = faHistory;\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterBy = 'all';\n public colWidth = '20rem';\n public PAGE_ID = 'on_chain';\n public tableSetting: TableSetting = { tableId: 'transaction', recordsPerPage: PAGE_SIZE, sortBy: 'timestamp', sortOrder: SortOrderEnum.DESCENDING };\n public displayedColumns: any[] = [];\n public listTransactions: any = new MatTableDataSource([]);\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public selFilter = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.store.dispatch(fetchTransactions());\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.push('actions');\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n this.store.select(transactions).pipe(takeUntil(this.unSubs[1])).\n subscribe((transactionsSelector: { transactions: Transaction[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = transactionsSelector.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n if (transactionsSelector.transactions) {\n this.loadTransactionsTable(transactionsSelector.transactions);\n }\n this.logger.info(transactionsSelector);\n });\n }\n\n applyFilter() {\n this.listTransactions.filter = this.selFilter.trim().toLowerCase();\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column, '_') : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.listTransactions.filterPredicate = (rowData: Transaction, fltr: string) => {\n let rowToFilter = '';\n switch (this.selFilterBy) {\n case 'all':\n rowToFilter = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp * 1000), 'dd/MMM/y HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();\n break;\n\n case 'timestamp':\n rowToFilter = this.datePipe.transform(new Date((rowData[this.selFilterBy] || 0) * 1000), 'dd/MMM/y HH:mm')?.toLowerCase() || '';\n break;\n\n default:\n rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();\n break;\n }\n return rowToFilter.includes(fltr);\n };\n }\n\n onTransactionClick(selTransaction: Transaction, event: any) {\n const reorderedTransactions = [\n [{ key: 'blockHash', value: selTransaction.blockHash, title: 'Block Hash', width: 100 }],\n [{ key: 'txid', value: selTransaction.txid, title: 'Transaction ID', width: 100 }],\n [{ key: 'timestamp', value: selTransaction.timestamp, title: 'Date/Time', width: 50, type: DataTypeEnum.DATE_TIME },\n { key: 'confirmations', value: selTransaction.confirmations, title: 'Number of Confirmations', width: 50, type: DataTypeEnum.NUMBER }],\n [{ key: 'fees', value: selTransaction.fees, title: 'Fees (Sats)', width: 50, type: DataTypeEnum.NUMBER },\n { key: 'amount', value: selTransaction.amount, title: 'Amount (Sats)', width: 50, type: DataTypeEnum.NUMBER }],\n [{ key: 'address', value: selTransaction.address, title: 'Address', width: 100, type: DataTypeEnum.STRING }]\n ];\n this.store.dispatch(openAlert({\n payload: {\n data: {\n type: AlertTypeEnum.INFORMATION,\n alertTitle: 'Transaction Information',\n message: reorderedTransactions\n }\n }\n }));\n }\n\n loadTransactionsTable(transactions: Transaction[]) {\n this.listTransactions = new MatTableDataSource<Transaction>([...transactions]);\n this.listTransactions.sort = this.sort;\n this.listTransactions.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);\n this.listTransactions.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.listTransactions.paginator = this.paginator;\n this.setFilterPredicate();\n this.applyFilter();\n this.logger.info(this.listTransactions);\n }\n\n onDownloadCSV() {\n if (this.listTransactions.data && this.listTransactions.data.length > 0) {\n this.commonService.downloadFile(this.listTransactions.data, 'Transactions');\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"row\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faChartPie\"></fa-icon>\n <span class=\"page-title\">On-chain Balance</span>\n</div>\n<div fxLayout=\"column\" class=\"padding-gap-x mb-4\">\n <mat-card>\n <mat-card-content fxLayout=\"column\">\n <rtl-currency-unit-converter [values]=\"balances\"></rtl-currency-unit-converter>\n </mat-card-content>\n </mat-card>\n</div>\n<div fxLayout=\"row\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faExchangeAlt\"></fa-icon>\n <span class=\"page-title\">On-chain Transactions</span>\n</div>\n<div fxLayout=\"column\" class=\"padding-gap-x\">\n <mat-card>\n <mat-card-content fxLayout=\"column\">\n <nav mat-tab-nav-bar [tabPanel]=\"tabPanel\">\n <div *ngFor=\"let link of links\" mat-tab-link class=\"mat-tab-label\" [active]=\"activeLink === link.link\" routerLink=\"{{link.link}}\" (click)=\"activeLink = link.link\">{{link.name}}</div>\n </nav>\n <mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>\n <!-- <nav mat-tab-nav-bar>\n <div role=\"tab\" mat-tab-link *ngFor=\"let link of links\" class=\"mat-tab-label\" [active]=\"activeLink === link.link\" (click)=\"activeLink = link.link\" routerLink=\"{{link.link}}\">{{link.name}}</div>\n </nav> -->\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" class=\"padding-gap-x-large mt-2\">\n <router-outlet></router-outlet>\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" class=\"padding-gap-x-large\">\n <rtl-ecl-on-chain-transaction-history fxLayout=\"row\" fxFlex=\"100\"></rtl-ecl-on-chain-transaction-history>\n </div>\n </mat-card-content>\n </mat-card>\n</div>\n","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Router, ResolveEnd, Event } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { faExchangeAlt, faChartPie } from '@fortawesome/free-solid-svg-icons';\n\nimport { ECLOnChainSendModalComponent } from './on-chain-send-modal/on-chain-send-modal.component';\nimport { SelNodeChild } from '../../shared/models/RTLconfig';\nimport { RTLState } from '../../store/rtl.state';\nimport { openAlert } from '../../store/rtl.actions';\nimport { eclNodeSettings, onchainBalance } from '../store/ecl.selector';\nimport { OnChainBalance } from '../../shared/models/eclModels';\nimport { ApiCallStatusPayload } from '../../shared/models/apiCallsPayload';\n\n@Component({\n selector: 'rtl-ecl-on-chain',\n templateUrl: './on-chain.component.html',\n styleUrls: ['./on-chain.component.scss']\n})\nexport class ECLOnChainComponent implements OnInit, OnDestroy {\n\n public selNode: SelNodeChild | null = {};\n public faExchangeAlt = faExchangeAlt;\n public faChartPie = faChartPie;\n public balances = [{ title: 'Total Balance', dataValue: 0 }, { title: 'Confirmed', dataValue: 0 }, { title: 'Unconfirmed', dataValue: 0 }];\n public links = [{ link: 'receive', name: 'Receive' }, { link: 'send', name: 'Send' }];\n public activeLink = this.links[0].link;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private store: Store<RTLState>, private router: Router) { }\n\n ngOnInit() {\n const linkFound = this.links.find((link) => this.router.url.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n this.router.events.pipe(takeUntil(this.unSubs[0]), filter((e) => e instanceof ResolveEnd)).\n subscribe({\n next: (value: ResolveEnd | Event) => {\n const linkFound = this.links.find((link) => (<ResolveEnd>value).urlAfterRedirects.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n }\n });\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[1])).\n subscribe((nodeSettings) => {\n this.selNode = nodeSettings;\n });\n this.store.select(onchainBalance).pipe(takeUntil(this.unSubs[2])).\n subscribe((oCBalanceSelector: { onchainBalance: OnChainBalance, apiCallStatus: ApiCallStatusPayload }) => {\n this.balances = [{ title: 'Total Balance', dataValue: oCBalanceSelector.onchainBalance.total || 0 }, { title: 'Confirmed', dataValue: (oCBalanceSelector.onchainBalance.confirmed || 0) }, { title: 'Unconfirmed', dataValue: (oCBalanceSelector.onchainBalance.unconfirmed || 0) }];\n });\n }\n\n openSendFundsModal() {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n component: ECLOnChainSendModalComponent\n }\n }\n }));\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"row\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faChartPie\"></fa-icon>\n <span class=\"page-title\">On-chain Balance</span>\n</div>\n<div fxLayout=\"column\" class=\"padding-gap-x mb-4\">\n <mat-card>\n <mat-card-content fxLayout=\"column\">\n <rtl-currency-unit-converter [values]=\"balances\"></rtl-currency-unit-converter>\n </mat-card-content>\n </mat-card>\n</div>\n<div fxLayout=\"row\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faUsers\"></fa-icon>\n <span class=\"page-title\">Connections</span>\n</div>\n<div fxLayout=\"column\" class=\"padding-gap-x\">\n <mat-card>\n <mat-card-content fxLayout=\"column\">\n <mat-tab-group [(selectedIndex)]=\"activeLink\" (selectedTabChange)=\"onSelectedTabChange($event)\">\n <mat-tab>\n <ng-template mat-tab-label>\n <span matBadgeOverlap=\"false\" class=\"tab-badge\" matBadge=\"{{activeChannels}}\">Channels</span>\n </ng-template>\n </mat-tab>\n <mat-tab>\n <ng-template mat-tab-label>\n <span matBadgeOverlap=\"false\" class=\"tab-badge\" matBadge=\"{{activePeers}}\">Peers</span>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" class=\"padding-gap-x-large\">\n <router-outlet></router-outlet>\n </div>\n </mat-card-content>\n </mat-card>\n</div>","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Router, ResolveEnd, Event } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { faUsers, faChartPie } from '@fortawesome/free-solid-svg-icons';\n\nimport { RTLState } from '../../store/rtl.state';\nimport { allChannelsInfo, onchainBalance, peers } from '../store/ecl.selector';\nimport { ApiCallStatusPayload } from '../../shared/models/apiCallsPayload';\nimport { Channel, ChannelsStatus, LightningBalance, OnChainBalance, Peer } from '../../shared/models/eclModels';\n\n@Component({\n selector: 'rtl-ecl-connections',\n templateUrl: './connections.component.html',\n styleUrls: ['./connections.component.scss']\n})\nexport class ECLConnectionsComponent implements OnInit, OnDestroy {\n\n public activePeers = 0;\n public activeChannels = 0;\n public faUsers = faUsers;\n public faChartPie = faChartPie;\n public balances = [{ title: 'Total Balance', dataValue: 0 }, { title: 'Confirmed', dataValue: 0 }, { title: 'Unconfirmed', dataValue: 0 }];\n public links = [{ link: 'channels', name: 'Channels' }, { link: 'peers', name: 'Peers' }];\n public activeLink = 0;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private store: Store<RTLState>, private router: Router) { }\n\n ngOnInit() {\n this.activeLink = this.links.findIndex((link) => link.link === this.router.url.substring(this.router.url.lastIndexOf('/') + 1));\n this.router.events.pipe(takeUntil(this.unSubs[0]), filter((e) => e instanceof ResolveEnd)).\n subscribe({\n next: (value: ResolveEnd | Event) => {\n this.activeLink = this.links.findIndex((link) => link.link === (<ResolveEnd>value).urlAfterRedirects.substring((<ResolveEnd>value).urlAfterRedirects.lastIndexOf('/') + 1));\n }\n });\n this.store.select(peers).pipe(takeUntil(this.unSubs[1])).\n subscribe((peersSelector: { peers: Peer[], apiCallStatus: ApiCallStatusPayload }) => {\n this.activePeers = (peersSelector.peers && peersSelector.peers.length) ? peersSelector.peers.length : 0;\n });\n this.store.select(allChannelsInfo).pipe(takeUntil(this.unSubs[2])).\n subscribe((allChannelsSelector: ({ activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], lightningBalance: LightningBalance, channelsStatus: ChannelsStatus, apiCallStatus: ApiCallStatusPayload })) => {\n this.activeChannels = allChannelsSelector.channelsStatus && allChannelsSelector.channelsStatus.active && allChannelsSelector.channelsStatus.active.channels ? allChannelsSelector.channelsStatus.active.channels : 0;\n });\n this.store.select(onchainBalance).pipe(takeUntil(this.unSubs[3])).\n subscribe((oCBalanceSelector: { onchainBalance: OnChainBalance, apiCallStatus: ApiCallStatusPayload }) => {\n this.balances = [{ title: 'Total Balance', dataValue: oCBalanceSelector.onchainBalance.total || 0 }, { title: 'Confirmed', dataValue: (oCBalanceSelector.onchainBalance.confirmed || 0) }, { title: 'Unconfirmed', dataValue: (oCBalanceSelector.onchainBalance.unconfirmed || 0) }];\n });\n }\n\n onSelectedTabChange(event) {\n this.router.navigateByUrl('/ecl/connections/' + this.links[event.index].link);\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"row wrap\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faChartPie\"></fa-icon>\n <span class=\"page-title\">Lightning Balance</span>\n</div>\n<div fxLayout=\"column\" class=\"padding-gap-x mb-4\">\n <mat-card>\n <mat-card-content fxLayout=\"column\">\n <rtl-currency-unit-converter [values]=\"balances\"></rtl-currency-unit-converter>\n </mat-card-content>\n </mat-card>\n</div>\n<div fxLayout=\"row\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faExchangeAlt\"></fa-icon>\n <span class=\"page-title\">Lightning Transactions</span>\n</div>\n<div fxLayout=\"column\" class=\"padding-gap-x\">\n <mat-card>\n <mat-card-content fxLayout=\"column\">\n <nav mat-tab-nav-bar [tabPanel]=\"tabPanel\">\n <div *ngFor=\"let link of links\" mat-tab-link class=\"mat-tab-label\" [active]=\"activeLink === link.link\" routerLink=\"{{link.link}}\" (click)=\"activeLink = link.link\">{{link.name}}</div>\n </nav>\n <mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>\n <!-- <nav mat-tab-nav-bar>\n <div role=\"tab\" mat-tab-link *ngFor=\"let link of links\" class=\"mat-tab-label\" [active]=\"activeLink === link.link\" (click)=\"activeLink = link.link\" routerLink=\"{{link.link}}\">{{link.name}}</div>\n </nav> -->\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" class=\"mat-tab-body-wrapper\">\n <router-outlet></router-outlet>\n </div>\n </mat-card-content>\n </mat-card>\n</div>\n ","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Router, ResolveEnd, Event } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter, withLatestFrom } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { faExchangeAlt, faChartPie } from '@fortawesome/free-solid-svg-icons';\n\nimport { UserPersonaEnum } from '../../shared/services/consts-enums-functions';\nimport { LoggerService } from '../../shared/services/logger.service';\nimport { RTLState } from '../../store/rtl.state';\nimport { eclNodeSettings, allChannelsInfo } from '../store/ecl.selector';\nimport { Channel, ChannelsStatus, LightningBalance } from '../../shared/models/eclModels';\nimport { ApiCallStatusPayload } from '../../shared/models/apiCallsPayload';\nimport { SelNodeChild } from '../../shared/models/RTLconfig';\n\n@Component({\n selector: 'rtl-ecl-transactions',\n templateUrl: './transactions.component.html',\n styleUrls: ['./transactions.component.scss']\n})\nexport class ECLTransactionsComponent implements OnInit, OnDestroy {\n\n faExchangeAlt = faExchangeAlt;\n faChartPie = faChartPie;\n currencyUnits: string[] = [];\n balances = [{ title: 'Local Capacity', dataValue: 0, tooltip: 'Amount you can send' }, { title: 'Remote Capacity', dataValue: 0, tooltip: 'Amount you can receive' }];\n public links = [{ link: 'payments', name: 'Payments' }, { link: 'invoices', name: 'Invoices' }];\n public activeLink = this.links[0].link;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private store: Store<RTLState>, private router: Router) { }\n\n ngOnInit() {\n const linkFound = this.links.find((link) => this.router.url.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n this.router.events.pipe(takeUntil(this.unSubs[0]), filter((e) => e instanceof ResolveEnd)).\n subscribe({\n next: (value: ResolveEnd | Event) => {\n const linkFound = this.links.find((link) => (<ResolveEnd>value).urlAfterRedirects.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n }\n });\n this.store.select(allChannelsInfo).pipe(takeUntil(this.unSubs[1]),\n withLatestFrom(this.store.select(eclNodeSettings))).\n subscribe(([allChannels, nodeSettings]: [{ activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], lightningBalance: LightningBalance, channelsStatus: ChannelsStatus, apiCallStatus: ApiCallStatusPayload }, (SelNodeChild | null)]) => {\n this.currencyUnits = nodeSettings?.currencyUnits || [];\n if (nodeSettings && nodeSettings.userPersona === UserPersonaEnum.OPERATOR) {\n this.balances = [{ title: 'Local Capacity', dataValue: allChannels.lightningBalance.localBalance, tooltip: 'Amount you can send' }, { title: 'Remote Capacity', dataValue: allChannels.lightningBalance.remoteBalance, tooltip: 'Amount you can receive' }];\n } else {\n this.balances = [{ title: 'Outbound Capacity', dataValue: allChannels.lightningBalance.localBalance, tooltip: 'Amount you can send' }, { title: 'Inbound Capacity', dataValue: allChannels.lightningBalance.remoteBalance, tooltip: 'Amount you can receive' }];\n }\n this.logger.info(allChannels);\n });\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faMapSigns\"></fa-icon>\n <span class=\"page-title\">Routing</span>\n </div>\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"start start\" class=\"padding-gap-x\">\n <mat-card fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"start start\">\n <mat-card-content fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start stretch\">\n <div fxLayout=\"row\" fxFlex=\"100\">\n <nav mat-tab-nav-bar fxFlex=\"100\" [tabPanel]=\"tabPanel\">\n <div *ngFor=\"let link of links\" mat-tab-link class=\"mat-tab-label\" [active]=\"activeLink === link.link\" routerLink=\"{{link.link}}\" (click)=\"activeLink = link.link\">{{link.name}}</div>\n </nav>\n <mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>\n <!-- <nav mat-tab-nav-bar fxFlex=\"100\">\n <div role=\"tab\" mat-tab-link *ngFor=\"let link of links\" class=\"mat-tab-label\" [active]=\"activeLink === link.link\" (click)=\"activeLink = link.link\" routerLink=\"{{link.link}}\">{{link.name}}</div>\n </nav> -->\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start stretch\" class=\"padding-gap-x-large\">\n <router-outlet></router-outlet>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Router, ResolveEnd, Event } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { faMapSigns } from '@fortawesome/free-solid-svg-icons';\n\n\n@Component({\n selector: 'rtl-ecl-routing',\n templateUrl: './routing.component.html',\n styleUrls: ['./routing.component.scss']\n})\nexport class ECLRoutingComponent implements OnInit, OnDestroy {\n\n public faMapSigns = faMapSigns;\n public events = [];\n public flgLoading: Array<Boolean | 'error'> = [true];\n public errorMessage = '';\n public links = [{ link: 'forwardinghistory', name: 'Forwarding History' }, { link: 'peers', name: 'Routing Peers' }];\n public activeLink = this.links[0].link;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];\n\n constructor(private router: Router) { }\n\n ngOnInit() {\n const linkFound = this.links.find((link) => this.router.url.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n this.router.events.pipe(takeUntil(this.unSubs[0]), filter((e) => e instanceof ResolveEnd)).\n subscribe({\n next: (value: ResolveEnd | Event) => {\n const linkFound = this.links.find((link) => (<ResolveEnd>value).urlAfterRedirects.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n }\n });\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div *ngIf=\"lookupResult\" fxLayout=\"column\">\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"30\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Alias</h4>\n <span class=\"foreground-secondary-text\">{{lookupResult?.alias}}<span class=\"ml-2\" [ngStyle]=\"{'background-color': lookupResult?.rgbColor}\">{{lookupResult?.rgbColor ? lookupResult?.rgbColor : ''}}</span></span>\n </div>\n <div fxFlex=\"70\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Pub Key</h4>\n <span class=\"foreground-secondary-text w-100\">{{lookupResult?.nodeId}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"30\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Date/Time</h4>\n <span class=\"foreground-secondary-text\">{{(lookupResult?.timestamp * 1000) | date:'dd/MMM/y HH:mm'}}</span>\n </div>\n <div fxFlex=\"70\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Features</h4>\n <span *ngFor=\"let activeFeature of lookupResult?.features.activated | keyvalue\" class=\"foreground-secondary-text w-100\"><div>{{nodeFeaturesEnum[activeFeature.key] || activeFeature.key}}: {{activeFeature.value | titlecase}}</div></span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Signature</h4>\n <span class=\"foreground-secondary-text\">{{lookupResult?.signature}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"column\">\n <h4 fxFlex=\"100\" fxLayoutAlign=\"start\" class=\"font-bold-500 mb-1\">Addresses</h4>\n <div fxLayout=\"row\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <table #table mat-table matSort class=\"overflow-auto\" [dataSource]=\"addresses\">\n <ng-container matColumnDef=\"address\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Address</th>\n <td *matCellDef=\"let address\" mat-cell>{{address}}</td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select btn-action\" fxLayoutAlign=\"center center\">Actions</div>\n </th>\n <td *matCellDef=\"let address\" mat-cell>\n <span fxLayoutAlign=\"end center\">\n <button mat-stroked-button class=\"btn-action-copy\" color=\"primary\" type=\"button\" tabindex=\"1\" rtlClipboard [payload]=\"lookupResult?.nodeId + '@' + address\" (copied)=\"onCopyNodeURI($event)\">Copy Node URI</button>\n </span>\n </td>\n </ng-container>\n <tr *matHeaderRowDef=\"displayedColumns;\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr> \n </table>\n </div>\n </div>\n</div>\n","import { Component, OnInit, Input, ViewChild } from '@angular/core';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\n\nimport { LookupNode } from '../../../../shared/models/eclModels';\nimport { NodeFeaturesECL } from '../../../../shared/services/consts-enums-functions';\nimport { LoggerService } from '../../../../shared/services/logger.service';\n\n@Component({\n selector: 'rtl-ecl-node-lookup',\n templateUrl: './node-lookup.component.html',\n styleUrls: ['./node-lookup.component.scss']\n})\nexport class ECLNodeLookupComponent implements OnInit {\n\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @Input() lookupResult: LookupNode = {};\n public addresses: any = new MatTableDataSource([]);\n public displayedColumns = ['address', 'actions'];\n public nodeFeaturesEnum = NodeFeaturesECL;\n\n constructor(private logger: LoggerService, private snackBar: MatSnackBar) { }\n\n ngOnInit() {\n this.addresses = this.lookupResult.addresses ? new MatTableDataSource<any>([...this.lookupResult.addresses]) : new MatTableDataSource([]);\n this.addresses.data = this.lookupResult.addresses || [];\n this.addresses.sort = this.sort;\n this.addresses.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);\n }\n\n onCopyNodeURI(payload: string) {\n this.snackBar.open('Node URI copied.');\n this.logger.info('Copied Text: ' + payload);\n }\n\n}\n","<div fxLayout=\"column\">\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"start start\" class=\"padding-gap\">\n <mat-card-content fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <form #form=\"ngForm\" fxFlex=\"100\" fxLayout=\"column\" fxLayout.gt-sm=\"row wrap\" fxLayoutAlign.gt-sm=\"space-between center\" fxLayoutAlign=\"start space-between\" class=\"w-100\">\n <div fxFlex=\"100\" fxLayoutAlign=\"start end\">\n <!-- <mat-radio-group color=\"primary\" [(ngModel)]=\"selectedFieldId\" (change)=\"onSelectChange($event)\" tabindex=\"1\" name=\"lookupField\">\n <mat-radio-button *ngFor=\"let lookupField of lookupFields\" [value]=\"lookupField.id\" [checked]=\"selectedFieldId === lookupField.id\" class=\"mr-4\">\n {{lookupField.name}}\n </mat-radio-button>\n </mat-radio-group> -->\n <mat-radio-group color=\"primary\" tabindex=\"1\" name=\"lookupField\">\n <mat-radio-button checked class=\"mr-4\" [value]=\"0\">Node</mat-radio-button>\n </mat-radio-group>\n </div>\n <mat-form-field fxFlex=\"100\" fxLayoutAlign=\"start end\" [ngClass]=\"{'mt-1': true, 'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}\">\n <!-- <input matInput name=\"lookupKey\" [placeholder]=\"lookupFields[selectedFieldId]?.placeholder || 'Lookup Key'\" (change)=\"clearLookupValue()\" [(ngModel)]=\"lookupKey\" tabindex=\"2\" required #key> -->\n <input #key matInput name=\"lookupKey\" tabindex=\"2\" required [formControl]=\"lookupKeyCtrl\" [placeholder]=\"lookupFields[selectedFieldId]?.placeholder || 'Lookup Key'\">\n <mat-error *ngIf=\"lookupKeyCtrl.errors?.required\">{{lookupFields[selectedFieldId]?.placeholder}} is required.</mat-error>\n <mat-error *ngIf=\"lookupKeyCtrl.errors?.invalid\">Invalid {{lookupFields[selectedFieldId]?.placeholder}}.</mat-error>\n </mat-form-field>\n <div fxLayout=\"row\" fxFlex=\"100\" class=\"mt-1\">\n <button class=\"mr-1\" mat-stroked-button color=\"primary\" tabindex=\"3\" type=\"button\" (click)=\"resetData()\">Clear</button>\n <button mat-flat-button color=\"primary\" tabindex=\"4\" type=\"submit\" (click)=\"onLookup()\">Lookup</button>\n </div>\n </form> \n <div *ngIf=\"flgSetLookupValue\" fxFlex=\"100\" fxLayout=\"column\" fxLayout.gt-sm=\"row wrap\" fxLayoutAlign.gt-sm=\"space-between center\" fxLayoutAlign=\"start stretch\" class=\"w-100 mt-2\">\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"start center\">\n <span class=\"page-title font-bold-500\">{{lookupFields[selectedFieldId].name}} Details</span>\n </div>\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"start center\" [ngSwitch]=\"selectedFieldId\">\n <span *ngSwitchCase=\"0\" fxFlex=\"100\"><div *ngIf=\"nodeLookupValue.nodeId; else errorBlock\"><rtl-ecl-node-lookup [lookupResult]=\"nodeLookupValue\"></rtl-ecl-node-lookup></div></span>\n <!-- <span fxFlex=\"100\" *ngSwitchCase=\"1\"><div *ngIf=\"channelLookupValue.length>0; else errorBlock\"><rtl-cln-channel-lookup [lookupResult]=\"channelLookupValue\"></rtl-cln-channel-lookup></div></span> -->\n <span *ngSwitchDefault> fxFlex=\"100\"<h3>Error! Unable to find details!</h3></span>\n </div>\n </div> \n </mat-card-content>\n </div>\n</div>\n<ng-template #errorBlock>\n <h3>Error! Unable to find details!</h3>\n</ng-template>","import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';\nimport { UntypedFormControl } from '@angular/forms';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { Actions } from '@ngrx/effects';\nimport { faSearch } from '@fortawesome/free-solid-svg-icons';\n\nimport { APICallStatusEnum, ECLActions, ScreenSizeEnum } from '../../../shared/services/consts-enums-functions';\nimport { CommonService } from '../../../shared/services/common.service';\nimport { LookupNode } from '../../../shared/models/eclModels';\nimport { LoggerService } from '../../../shared/services/logger.service';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { peerLookup } from '../../store/ecl.actions';\n\n@Component({\n selector: 'rtl-ecl-lookups',\n templateUrl: './lookups.component.html',\n styleUrls: ['./lookups.component.scss']\n})\nexport class ECLLookupsComponent implements OnInit, OnDestroy {\n\n @ViewChild('form', { static: true }) form: any;\n public lookupKeyCtrl = new UntypedFormControl();\n // Public lookupKey = '';\n public nodeLookupValue: LookupNode = {};\n public channelLookupValue = [];\n public flgSetLookupValue = false;\n public messageObj = [];\n public selectedFieldId = 0;\n public lookupFields = [\n { id: 0, name: 'Node', placeholder: 'Node ID' },\n { id: 1, name: 'Channel', placeholder: 'Short Channel ID' }\n ];\n public flgLoading: Array<Boolean | 'error'> = [true];\n public faSearch = faSearch;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private actions: Actions) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.actions.pipe(\n takeUntil(this.unSubs[0]),\n filter((action) => (action.type === ECLActions.SET_LOOKUP_ECL || action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL))).\n subscribe((resLookup: any) => {\n if (resLookup.type === ECLActions.SET_LOOKUP_ECL) {\n this.flgLoading[0] = true;\n switch (this.selectedFieldId) {\n case 0:\n this.nodeLookupValue = resLookup.payload[0] ? JSON.parse(JSON.stringify(resLookup.payload[0])) : { nodeid: '' };\n break;\n case 1:\n this.channelLookupValue = JSON.parse(JSON.stringify(resLookup.payload)) || [];\n break;\n default:\n break;\n }\n this.flgSetLookupValue = true;\n this.logger.info(this.nodeLookupValue);\n this.logger.info(this.channelLookupValue);\n }\n if (resLookup.type === ECLActions.UPDATE_API_CALL_STATUS_ECL && resLookup.payload.status === APICallStatusEnum.ERROR && resLookup.payload.action === 'Lookup') {\n this.flgLoading[0] = 'error';\n }\n });\n this.lookupKeyCtrl.valueChanges.pipe(takeUntil(this.unSubs[1])).subscribe((value) => {\n this.nodeLookupValue = {};\n this.channelLookupValue = [];\n this.flgSetLookupValue = false;\n });\n }\n\n onLookup(): boolean | void {\n if (!this.lookupKeyCtrl.value) {\n this.lookupKeyCtrl.setErrors({ required: true });\n return true;\n } else if (this.lookupKeyCtrl.value && (this.lookupKeyCtrl.value.includes('@') || this.lookupKeyCtrl.value.includes(','))) {\n this.lookupKeyCtrl.setErrors({ invalid: true });\n return true;\n } else {\n if (!this.selectedFieldId) {\n this.selectedFieldId = 0;\n }\n this.flgSetLookupValue = false;\n this.nodeLookupValue = {};\n this.channelLookupValue = [];\n switch (this.selectedFieldId) {\n case 0:\n this.store.dispatch(peerLookup({ payload: this.lookupKeyCtrl.value.trim() }));\n break;\n case 1:\n // this.store.dispatch(channelLookup({ payload: {shortChannelID: this.lookupKey.trim(), showError: false} }));\n break;\n default:\n break;\n }\n }\n }\n\n onSelectChange(event: any) {\n this.resetData();\n this.selectedFieldId = event.value;\n }\n\n resetData() {\n this.flgSetLookupValue = false;\n this.nodeLookupValue = {};\n this.channelLookupValue = [];\n this.lookupKeyCtrl.setValue('');\n this.lookupKeyCtrl.setErrors(null);\n this.form.resetForm();\n }\n\n clearLookupValue() {\n this.nodeLookupValue = {};\n this.channelLookupValue = [];\n this.flgSetLookupValue = false;\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","import { Component } from '@angular/core';\nimport { take } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\n\nimport { OnChainGeneratedAddressComponent } from '../../../shared/components/data-modal/on-chain-generated-address/on-chain-generated-address.component';\n\nimport { ECLEffects } from '../../store/ecl.effects';\nimport { RTLState } from '../../../store/rtl.state';\nimport { openAlert } from '../../../store/rtl.actions';\nimport { getNewAddress } from '../../store/ecl.actions';\n\n@Component({\n selector: 'rtl-ecl-on-chain-receive',\n templateUrl: './on-chain-receive.component.html',\n styleUrls: ['./on-chain-receive.component.scss']\n})\nexport class ECLOnChainReceiveComponent {\n\n public newAddress = '';\n\n constructor(private store: Store<RTLState>, private eclEffects: ECLEffects) { }\n\n onGenerateAddress() {\n this.store.dispatch(getNewAddress());\n this.eclEffects.setNewAddress.pipe(take(1)).subscribe((newAddress) => {\n this.newAddress = newAddress;\n setTimeout(() => {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n address: this.newAddress,\n addressType: '',\n component: OnChainGeneratedAddressComponent\n }\n }\n }));\n }, 0);\n });\n }\n\n}\n","<div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <div fxLayout=\"row\">\n <button mat-flat-button color=\"primary\" tabindex=\"1\" (click)=\"onGenerateAddress()\">Generate Address</button>\n </div>\n</div>\n","import { Component, OnDestroy, OnInit } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\n\nimport { ECLOnChainSendModalComponent } from '../on-chain-send-modal/on-chain-send-modal.component';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { openAlert } from '../../../store/rtl.actions';\n\n@Component({\n selector: 'rtl-ecl-on-chain-send',\n templateUrl: './on-chain-send.component.html',\n styleUrls: ['./on-chain-send.component.scss']\n})\nexport class ECLOnChainSendComponent implements OnInit, OnDestroy {\n\n public sweepAll = false;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];\n\n constructor(private store: Store<RTLState>, private activatedRoute: ActivatedRoute) { }\n\n ngOnInit() {\n this.activatedRoute.data.pipe(takeUntil(this.unSubs[0])).subscribe((routeData) => {\n this.sweepAll = routeData.sweepAll;\n });\n }\n\n openSendFundsModal() {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n sweepAll: this.sweepAll,\n component: ECLOnChainSendModalComponent\n }\n }\n }));\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <div fxLayout=\"row\">\n <button mat-flat-button color=\"primary\" type=\"button\" tabindex=\"1\" (click)=\"openSendFundsModal()\">{{sweepAll ? 'Sweep All' : 'Send Funds'}}</button>\n </div>\n</div>\n","<div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <mat-card-header fxLayout=\"row\" fxLayoutAlign=\"space-between center\" class=\"modal-info-header\">\n <div fxFlex=\"95\" fxLayoutAlign=\"start start\">\n <span class=\"page-title\">{{alertTitle}}</span>\n </div>\n <button tabindex=\"11\" fxFlex=\"5\" fxLayoutAlign=\"center\" class=\"btn-close-x p-0\" mat-button (click)=\"onClose()\">X</button>\n </mat-card-header>\n <mat-card-content class=\"padding-gap-x-large\">\n <form #form=\"ngForm\" fxLayout=\"column\" (submit)=\"onOpenChannel()\" (reset)=\"resetData()\">\n <div fxLayout=\"column\">\n <mat-form-field *ngIf=\"!peer && peers && peers.length > 0\" fxFlex=\"100\">\n <input type=\"text\" placeholder=\"Peer Alias\" aria-label=\"Peers\" matInput tabindex=\"1\" required [formControl]=\"selectedPeer\" [matAutocomplete]=\"auto\" (change)=\"onSelectedPeerChanged()\">\n <mat-autocomplete #auto=\"matAutocomplete\" [displayWith]=\"displayFn\" (optionSelected)=\"onSelectedPeerChanged()\">\n <mat-option *ngFor=\"let peer of filteredPeers | async\" [value]=\"peer\">{{peer.alias ? peer.alias : peer.nodeId ? peer.nodeId : ''}}</mat-option>\n </mat-autocomplete>\n <mat-error *ngIf=\"selectedPeer.errors?.required\">Peer alias is required.</mat-error>\n <mat-error *ngIf=\"selectedPeer.errors?.notfound\">Peer not found in the list.</mat-error>\n </mat-form-field>\n </div>\n <ng-container *ngTemplateOutlet=\"peerDetailsExpansionBlock\"></ng-container>\n <div fxLayout=\"column\">\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between center\">\n <mat-form-field fxFlex=\"70\" fxLayoutAlign=\"start end\">\n <input #amount=\"ngModel\" matInput placeholder=\"Amount\" type=\"number\" tabindex=\"1\" required name=\"amount\" [step]=\"1000\" [min]=\"1\" [max]=\"totalBalance\" [(ngModel)]=\"fundingAmount\">\n <mat-hint>Remaining Bal: {{totalBalance - ((fundingAmount) ? fundingAmount : 0) | number}}</mat-hint>\n <span matSuffix> Sats </span>\n <mat-error *ngIf=\"amount.errors?.required\">Amount is required.</mat-error>\n <mat-error *ngIf=\"amount.errors?.max\">Amount must be less than or equal to {{totalBalance}}.</mat-error>\n </mat-form-field>\n <div fxFlex=\"25\" fxLayoutAlign=\"start center\">\n <mat-slide-toggle tabindex=\"2\" color=\"primary\" name=\"isPrivate\" [(ngModel)]=\"isPrivate\">Private Channel</mat-slide-toggle>\n </div>\n </div>\n <mat-expansion-panel class=\"flat-expansion-panel mt-2\" expanded=\"false\" (closed)=\"onAdvancedPanelToggle(true)\" (opened)=\"onAdvancedPanelToggle(false)\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <span>{{advancedTitle}}</span>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start stretch\">\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between center\">\n <div fxFlex=\"100\" fxLayout=\"row\" fxLayoutAlign=\"space-between center\">\n <mat-form-field fxFlex=\"49\">\n <input #fee=\"ngModel\" matInput placeholder=\"Fee (Sats/vByte)\" type=\"number\" name=\"fee\" tabindex=\"7\" [step]=\"1\" [min]=\"0\" [(ngModel)]=\"feeRate\">\n </mat-form-field>\n </div>\n </div>\n </div>\n </mat-expansion-panel> \n </div>\n <div *ngIf=\"channelConnectionError !== ''\" fxFlex=\"100\" class=\"alert alert-danger mt-1\">\n <fa-icon class=\"mr-1 alert-icon\" [icon]=\"faExclamationTriangle\"></fa-icon>\n <span *ngIf=\"channelConnectionError !== ''\">{{channelConnectionError}}</span>\n </div>\n <div class=\"mt-2\" fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button mat-button color=\"primary\" class=\"mr-1\" tabindex=\"9\" type=\"reset\">Clear Fields</button>\n <button autoFocus mat-button color=\"primary\" type=\"submit\" tabindex=\"10\">Open Channel</button>\n </div>\n </form>\n </mat-card-content>\n </div>\n</div>\n\n<ng-template #peerDetailsExpansionBlock>\n <mat-expansion-panel *ngIf=\"peer\" class=\"flat-expansion-panel my-1\" expanded=\"false\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <span>Peer: &nbsp;</span><strong class=\"font-weight-900\">{{peer?.alias || peer?.nodeId}}</strong>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div fxLayout=\"column\">\n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Pubkey</h4>\n <span class=\"foreground-secondary-text\">{{peer.nodeId}}</span>\n </div>\n </div>\n <mat-divider class=\"w-100 my-1\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Address</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{peer?.address}}</span>\n </div>\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">State</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{peer?.state | titlecase}}</span>\n </div>\n </div>\n </div>\n </mat-expansion-panel>\n</ng-template>\n","import { Component, OnInit, Inject, OnDestroy, ViewChild } from '@angular/core';\nimport { UntypedFormControl } from '@angular/forms';\nimport { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';\nimport { Subject, Observable } from 'rxjs';\nimport { takeUntil, filter, startWith, map } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { Actions } from '@ngrx/effects';\nimport { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';\n\nimport { Peer, GetInfo, SaveChannel } from '../../../../shared/models/eclModels';\nimport { APICallStatusEnum, ECLActions } from '../../../../shared/services/consts-enums-functions';\nimport { ECLOpenChannelAlert } from '../../../../shared/models/alertData';\n\nimport { RTLState } from '../../../../store/rtl.state';\nimport { saveNewChannel } from '../../../store/ecl.actions';\nimport { SelNodeChild } from '../../../../shared/models/RTLconfig';\nimport { eclNodeSettings } from '../../../store/ecl.selector';\n\n@Component({\n selector: 'rtl-ecl-open-channel',\n templateUrl: './open-channel.component.html',\n styleUrls: ['./open-channel.component.scss']\n})\nexport class ECLOpenChannelComponent implements OnInit, OnDestroy {\n\n @ViewChild('form', { static: true }) form: any;\n public selNode: SelNodeChild | null = {};\n public selectedPeer = new UntypedFormControl();\n public faExclamationTriangle = faExclamationTriangle;\n public alertTitle: string;\n public peer: Peer | null;\n public peers: Peer[];\n public sortedPeers: Peer[];\n public filteredPeers: Observable<Peer[]>;\n public channelConnectionError = '';\n public advancedTitle = 'Advanced Options';\n public information: GetInfo;\n public totalBalance = 0;\n public fundingAmount: number | null;\n public selectedPubkey = '';\n public isPrivate = false;\n public feeRate: number | null = null;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(public dialogRef: MatDialogRef<ECLOpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: ECLOpenChannelAlert, private store: Store<RTLState>, private actions: Actions) { }\n\n ngOnInit() {\n if (this.data.message) {\n this.information = this.data.message.information;\n this.totalBalance = this.data.message.balance;\n this.peer = this.data.message.peer || null;\n this.peers = this.data.message.peers || [];\n } else {\n this.information = {};\n this.totalBalance = 0;\n this.peer = null;\n this.peers = [];\n }\n this.alertTitle = this.data.alertTitle || 'Alert';\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((nodeSettings: SelNodeChild | null) => {\n this.selNode = nodeSettings;\n this.isPrivate = !!nodeSettings?.unannouncedChannels;\n });\n this.actions.pipe(\n takeUntil(this.unSubs[1]),\n filter((action) => action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL || action.type === ECLActions.FETCH_CHANNELS_ECL)).\n subscribe((action: any) => {\n if (action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL && action.payload.status === APICallStatusEnum.ERROR && action.payload.action === 'SaveNewChannel') {\n this.channelConnectionError = action.payload.message;\n }\n if (action.type === ECLActions.FETCH_CHANNELS_ECL) {\n this.dialogRef.close();\n }\n });\n let x = '';\n let y = '';\n this.sortedPeers = this.peers.sort((p1, p2) => {\n x = p1.alias ? p1.alias.toLowerCase() : p1.nodeId ? p1.nodeId.toLowerCase() : '';\n y = p2.alias ? p2.alias.toLowerCase() : p1.nodeId ? p1.nodeId.toLowerCase() : '';\n return ((x < y) ? -1 : ((x > y) ? 1 : 0));\n });\n this.filteredPeers = this.selectedPeer.valueChanges.pipe(\n takeUntil(this.unSubs[2]), startWith(''),\n map((peer) => (typeof peer === 'string' ? peer : peer.alias ? peer.alias : peer.nodeId)),\n map((alias) => (alias ? this.filterPeers(alias) : this.sortedPeers.slice()))\n );\n }\n\n private filterPeers(newlySelectedPeer: string): Peer[] {\n return this.sortedPeers?.filter((peer) => peer.alias?.toLowerCase().indexOf(newlySelectedPeer ? newlySelectedPeer.toLowerCase() : '') === 0);\n }\n\n displayFn(peer: Peer): string {\n return (peer && peer.alias) ? peer.alias : (peer && peer.nodeId) ? peer.nodeId : '';\n }\n\n onSelectedPeerChanged() {\n this.channelConnectionError = '';\n this.selectedPubkey = (this.selectedPeer.value && this.selectedPeer.value.nodeId) ? this.selectedPeer.value.nodeId : null;\n if (typeof this.selectedPeer.value === 'string') {\n const selPeer = this.peers?.filter((peer) => peer.alias?.length === this.selectedPeer.value.length && peer.alias?.toLowerCase().indexOf(this.selectedPeer.value ? this.selectedPeer.value.toLowerCase() : '') === 0);\n if (selPeer.length === 1 && selPeer[0].nodeId) {\n this.selectedPubkey = selPeer[0].nodeId;\n }\n }\n if (this.selectedPeer.value && !this.selectedPubkey) {\n this.selectedPeer.setErrors({ notfound: true });\n } else {\n this.selectedPeer.setErrors(null);\n }\n }\n\n onClose() {\n this.dialogRef.close(false);\n }\n\n resetData() {\n this.feeRate = null;\n this.selectedPeer.setValue('');\n this.fundingAmount = null;\n this.isPrivate = !!this.selNode?.unannouncedChannels;\n this.channelConnectionError = '';\n this.advancedTitle = 'Advanced Options';\n this.form.resetForm();\n }\n\n onAdvancedPanelToggle(isClosed: boolean) {\n this.advancedTitle = 'Advanced Options';\n if (isClosed) {\n if (this.feeRate && this.feeRate > 0) {\n this.advancedTitle = this.advancedTitle + ' | Fee (Sats/vByte): ' + this.feeRate;\n }\n }\n }\n\n onOpenChannel(): boolean | void {\n if ((!this.peer && !this.selectedPubkey) || (!this.fundingAmount || ((this.totalBalance - this.fundingAmount) < 0))) {\n return true;\n }\n const saveChannelPayload: SaveChannel = { nodeId: ((!this.peer || !this.peer.nodeId) ? this.selectedPubkey : this.peer.nodeId), amount: this.fundingAmount, private: this.isPrivate };\n if (this.feeRate) { saveChannelPayload['feeRate'] = this.feeRate; }\n this.store.dispatch(saveNewChannel({ payload: saveChannelPayload }));\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <div fxLayout=\"row\">\n <button mat-flat-button color=\"primary\" type=\"submit\" tabindex=\"1\" (click)=\"onOpenChannel()\">Open Channel</button>\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" class=\"my-2 bordered-box\">\n <mat-tab-group [(selectedIndex)]=\"activeLink\" (selectedTabChange)=\"onSelectedTabChange($event)\">\n <mat-tab>\n <ng-template mat-tab-label>\n <span matBadgeOverlap=\"false\" class=\"tab-badge\" matBadge=\"{{numOfOpenChannels}}\">Open</span>\n </ng-template>\n </mat-tab>\n <mat-tab>\n <ng-template mat-tab-label>\n <span matBadgeOverlap=\"false\" class=\"tab-badge\" matBadge=\"{{numOfPendingChannels}}\">Pending</span>\n </ng-template>\n </mat-tab>\n <mat-tab>\n <ng-template mat-tab-label>\n <span matBadgeOverlap=\"false\" class=\"tab-badge\" matBadge=\"{{numOfInactiveChannels}}\">Inactive</span>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" class=\"padding-gap-x-large\">\n <router-outlet></router-outlet>\n </div>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Router, ResolveEnd, Event } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\n\nimport { ECLOpenChannelComponent } from '../open-channel-modal/open-channel.component';\nimport { LoggerService } from '../../../../shared/services/logger.service';\nimport { Channel, ChannelsStatus, GetInfo, LightningBalance, OnChainBalance, Peer } from '../../../../shared/models/eclModels';\nimport { SelNodeChild } from '../../../../shared/models/RTLconfig';\n\nimport { RTLState } from '../../../../store/rtl.state';\nimport { openAlert } from '../../../../store/rtl.actions';\nimport { allChannelsInfo, eclNodeInformation, eclNodeSettings, onchainBalance, peers } from '../../../store/ecl.selector';\nimport { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';\n\n@Component({\n selector: 'rtl-ecl-channels-tables',\n templateUrl: './channels-tables.component.html',\n styleUrls: ['./channels-tables.component.scss']\n})\nexport class ECLChannelsTablesComponent implements OnInit, OnDestroy {\n\n public numOfOpenChannels = 0;\n public numOfPendingChannels = 0;\n public numOfInactiveChannels = 0;\n public selNode: SelNodeChild | null = {};\n public information: GetInfo = {};\n public peers: Peer[] = [];\n public totalBalance = 0;\n public links = [{ link: 'open', name: 'Open' }, { link: 'pending', name: 'Pending' }, { link: 'inactive', name: 'Inactive' }];\n public activeLink = 0;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private store: Store<RTLState>, private router: Router) { }\n\n ngOnInit() {\n this.activeLink = this.links.findIndex((link) => link.link === this.router.url.substring(this.router.url.lastIndexOf('/') + 1));\n this.router.events.pipe(takeUntil(this.unSubs[0]), filter((e) => e instanceof ResolveEnd)).\n subscribe({\n next: (value: ResolveEnd | Event) => {\n this.activeLink = this.links.findIndex((link) => link.link === (<ResolveEnd>value).urlAfterRedirects.substring((<ResolveEnd>value).urlAfterRedirects.lastIndexOf('/') + 1));\n }\n });\n this.store.select(allChannelsInfo).pipe(takeUntil(this.unSubs[1])).\n subscribe((allChannelsSelector: ({ activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], lightningBalance: LightningBalance, channelsStatus: ChannelsStatus, apiCallStatus: ApiCallStatusPayload })) => {\n this.numOfOpenChannels = (allChannelsSelector.channelsStatus && allChannelsSelector.channelsStatus.active && allChannelsSelector.channelsStatus.active.channels) ? allChannelsSelector.channelsStatus.active.channels : 0;\n this.numOfPendingChannels = (allChannelsSelector.channelsStatus && allChannelsSelector.channelsStatus.pending && allChannelsSelector.channelsStatus.pending.channels) ? allChannelsSelector.channelsStatus.pending.channels : 0;\n this.numOfInactiveChannels = (allChannelsSelector.channelsStatus && allChannelsSelector.channelsStatus.inactive && allChannelsSelector.channelsStatus.inactive.channels) ? allChannelsSelector.channelsStatus.inactive.channels : 0;\n this.logger.info(allChannelsSelector);\n });\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[2])).\n subscribe((nodeSettings: SelNodeChild | null) => {\n this.selNode = nodeSettings;\n });\n this.store.select(eclNodeInformation).pipe(takeUntil(this.unSubs[3])).\n subscribe((nodeInfo: GetInfo) => {\n this.information = nodeInfo;\n });\n this.store.select(peers).pipe(takeUntil(this.unSubs[4])).\n subscribe((peersSelector: { peers: Peer[], apiCallStatus: ApiCallStatusPayload }) => {\n this.peers = peersSelector.peers;\n });\n this.store.select(onchainBalance).pipe(takeUntil(this.unSubs[5])).\n subscribe((oCBalanceSelector: { onchainBalance: OnChainBalance, apiCallStatus: ApiCallStatusPayload }) => {\n this.totalBalance = oCBalanceSelector.onchainBalance.total || 0;\n });\n }\n\n onOpenChannel() {\n const peerToAddChannelMessage = {\n peers: this.peers,\n information: this.information,\n balance: this.totalBalance\n };\n this.store.dispatch(openAlert({\n payload: {\n data: {\n alertTitle: 'Open Channel',\n message: peerToAddChannelMessage,\n component: ECLOpenChannelComponent\n }\n }\n }));\n }\n\n onSelectedTabChange(event) {\n this.router.navigateByUrl('/ecl/connections/channels/' + this.links[event.index].link);\n }\n\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxLayout.gt-sm=\"row\" fxLayoutAlign=\"space-between stretch\">\n <div fxFlex=\"100\">\n <mat-card-header fxLayout=\"row\" fxLayoutAlign=\"space-between center\" class=\"modal-info-header\">\n <div fxFlex=\"95\" fxLayoutAlign=\"start start\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faReceipt\"></fa-icon>\n <span class=\"page-title\">Channel Information</span>\n </div>\n <button tabindex=\"3\" fxFlex=\"5\" fxLayoutAlign=\"center\" class=\"btn-close-x p-0\" mat-button (click)=\"onClose()\">X</button>\n </mat-card-header>\n <mat-card-content class=\"padding-gap-x-large\" [ngClass]=\"{'xs-scroll-y': screenSize === screenSizeEnum.XS}\">\n <div fxLayout=\"column\">\n <div fxLayout=\"row\">\n <div *ngIf=\"channelsType === 'open'\" fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Short Channel ID</h4>\n <span class=\"foreground-secondary-text\">{{channel.shortChannelId}}</span>\n </div>\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Peer Alias</h4>\n <span class=\"foreground-secondary-text\">{{channel.alias}}</span>\n </div>\n <div *ngIf=\"channelsType !== 'open'\" fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">State</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{channel.state | titlecase}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Channel ID</h4>\n <span class=\"foreground-secondary-text\">{{channel.channelId}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Peer Public Key</h4>\n <span class=\"foreground-secondary-text\">{{channel.nodeId}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Private</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{!channel.announceChannel ? 'Yes' : 'No'}}</span>\n </div>\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Funder</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{channel.isFunder ? 'Yes' : 'No'}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">State</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{channel.state | titlecase}}</span>\n </div>\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Buried</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{channel.buried ? 'Yes' : 'No'}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div *ngIf=\"showAdvanced && channelsType === 'open'\">\n <div fxLayout=\"row\">\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Local Balance (Sats)</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{channel.toLocal | number}}</span>\n </div>\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Remote Balance (Sats)</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{channel.toRemote | number}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n <div fxLayout=\"row\">\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Base Fee (mSats)</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{channel.feeBaseMsat | number}}</span>\n </div>\n <div fxFlex=\"50\">\n <h4 fxLayoutAlign=\"start\" class=\"font-bold-500\">Fee Rate (mili mSats)</h4>\n <span class=\"overflow-wrap foreground-secondary-text\">{{channel.feeProportionalMillionths | number}}</span>\n </div>\n </div>\n <mat-divider class=\"my-1\" [inset]=\"true\"></mat-divider>\n </div>\n <div fxLayout=\"row\" fxLayoutAlign=\"end center\" fxFlex=\"100\" [ngClass]=\"{'mt-2': !showAdvanced, 'mt-1': showAdvanced}\">\n <button *ngIf=\"channelsType === 'open'\" mat-button color=\"primary\" type=\"reset\" tabindex=\"1\" class=\"mr-1\" (click)=\"onShowAdvanced()\">\n <p *ngIf=\"!showAdvanced; else hideAdvancedText\">Show Advanced</p>\n <ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>\n </button>\n <button *ngIf=\"channelsType === 'open'\" autoFocus mat-button color=\"primary\" tabindex=\"2\" type=\"submit\" rtlClipboard [payload]=\"channel.shortChannelId\" (copied)=\"onCopyChanID($event)\">Copy Short Channel ID</button>\n <button *ngIf=\"channelsType !== 'open'\" autoFocus mat-button color=\"primary\" tabindex=\"3\" type=\"submit\" rtlClipboard [payload]=\"channel.channelId\" (copied)=\"onCopyChanID($event)\">Copy Channel ID</button>\n </div>\n </div>\n </mat-card-content>\n </div>\n</div>\n","import { Component, OnInit, Inject } from '@angular/core';\nimport { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';\nimport { faReceipt } from '@fortawesome/free-solid-svg-icons';\nimport { MatSnackBar } from '@angular/material/snack-bar';\n\nimport { LoggerService } from '../../../../shared/services/logger.service';\nimport { CommonService } from '../../../../shared/services/common.service';\nimport { ECLChannelInformation } from '../../../../shared/models/alertData';\nimport { Channel } from '../../../../shared/models/eclModels';\nimport { ScreenSizeEnum } from '../../../../shared/services/consts-enums-functions';\n\n@Component({\n selector: 'rtl-ecl-channel-information',\n templateUrl: './channel-information.component.html',\n styleUrls: ['./channel-information.component.scss']\n})\nexport class ECLChannelInformationComponent implements OnInit {\n\n public faReceipt = faReceipt;\n public showAdvanced = false;\n public channel: Channel;\n public channelsType = 'open';\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n\n constructor(public dialogRef: MatDialogRef<ECLChannelInformationComponent>, @Inject(MAT_DIALOG_DATA) public data: ECLChannelInformation, private logger: LoggerService, private commonService: CommonService, private snackBar: MatSnackBar) { }\n\n ngOnInit() {\n this.channel = this.data.channel;\n this.channelsType = this.data.channelsType || '';\n this.screenSize = this.commonService.getScreenSize();\n }\n\n onClose() {\n this.dialogRef.close(false);\n }\n\n onShowAdvanced() {\n this.showAdvanced = !this.showAdvanced;\n }\n\n onCopyChanID(payload: string) {\n this.snackBar.open((this.channelsType === 'open') ? ('Short channel ID ' + payload + ' copied.') : 'Channel ID copied.');\n this.logger.info('Copied Text: ' + payload);\n }\n\n}\n","<div fxLayout=\"column\" class=\"padding-gap\">\n <div fxLayout=\"column\" fxLayout.gt-xs=\"row\" fxLayoutAlign.gt-xs=\"start center\" fxLayoutAlign=\"start stretch\" class=\"page-sub-title-container\">\n <div fxFlex=\"70\"></div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput name=\"filter\" placeholder=\"Filter\" [(ngModel)]=\"selFilter\" (input)=\"applyFilter()\" (keyup)=\"applyFilter()\">\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #table mat-table fxFlex=\"100\" matSort [dataSource]=\"channels\" [ngClass]=\"{'error-border': errorMessage !== ''}\">\n <ng-container matColumnDef=\"announceChannel\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header matTooltip=\"Private\"></th>\n <td *matCellDef=\"let channel\" mat-cell>\n <span *ngIf=\"!channel?.announceChannel\" class=\"mr-1\" matTooltip=\"Private\" matTooltipPosition=\"right\"><fa-icon [icon]=\"faEyeSlash\"></fa-icon></span>\n <span *ngIf=\"channel?.announceChannel\" class=\"mr-1\" matTooltip=\"Public\" matTooltipPosition=\"right\"><fa-icon [icon]=\"faEye\"></fa-icon></span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"shortChannelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Short Channel ID</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.shortChannelId}}</td>\n </ng-container>\n <ng-container matColumnDef=\"channelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Channel ID</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{channel?.channelId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"alias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Alias</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{channel?.alias}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"nodeId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Node ID</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{channel?.nodeId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"isFunder\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Funder</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.isFunder ? 'Yes' : 'No'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"buried\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Buried</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.buried ? 'Yes' : 'No'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"feeBaseMsat\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Base Fee (mSats)</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.feeBaseMsat | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"feeProportionalMillionths\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Fee Rate (mili mSats)</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.feeProportionalMillionths | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"toLocal\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Local Balance (Sats)</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.toLocal | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"toRemote\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Remote Balance (Sats)</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.toRemote | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"feeRatePerKw\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Fee/KW</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.feeRatePerKw | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"balancedness\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Balance Score</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div fxLayout=\"row\">\n <mat-hint fxFlex=\"100\" fxLayoutAlign=\"center center\" class=\"font-size-80\">{{channel?.balancedness || 0 | number}}</mat-hint>\n </div>\n <mat-progress-bar mode=\"determinate\" value=\"{{channel?.toLocal && channel?.toLocal > 0 ? ((+channel?.toLocal/((+channel?.toLocal)+(+channel?.toRemote)))*100) : 0}}\"></mat-progress-bar>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onChannelUpdate('all')\">Update Fee Policy</mat-option>\n <mat-option (click)=\"onDownloadCSV()\">Download CSV</mat-option>\n </mat-select>\n </div>\n </th> \n <td *matCellDef=\"let channel\" mat-cell fxLayoutAlign=\"end center\">\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"2\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onChannelClick(channel, $event)\">View Info</mat-option>\n <mat-option (click)=\"onChannelUpdate(channel)\">Update Fee Policy</mat-option>\n <mat-option (click)=\"onChannelClose(channel, false)\">Close Channel</mat-option>\n <mat-option (click)=\"onChannelClose(channel, true)\">Force Close</mat-option>\n </mat-select>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"no_peer\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"numPeers<1 && (!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No peers connected. Add a peer in order to open a channel?.</p>\n <p *ngIf=\"numPeers>0 && (!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No channel available.</p>\n <p *ngIf=\"(!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting channels...</p>\n <p *ngIf=\"(!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_peer']\" mat-footer-row [ngClass]=\"{'display-none': numPeers>0 && channels?.data && channels?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div>\n <mat-paginator class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild, AfterViewInit } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';\n\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\nimport { Channel, ChannelsStatus, GetInfo, LightningBalance, OnChainBalance, Peer } from '../../../../../shared/models/eclModels';\nimport { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, FEE_RATE_TYPES, AlertTypeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS, DataTypeEnum } from '../../../../../shared/services/consts-enums-functions';\nimport { LoggerService } from '../../../../../shared/services/logger.service';\nimport { CommonService } from '../../../../../shared/services/common.service';\n\nimport { ECLChannelInformationComponent } from '../../channel-information-modal/channel-information.component';\nimport { RTLEffects } from '../../../../../store/rtl.effects';\nimport { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';\nimport { openAlert, openConfirmation } from '../../../../../store/rtl.actions';\nimport { RTLState } from '../../../../../store/rtl.state';\nimport { closeChannel, updateChannel } from '../../../../store/ecl.actions';\nimport { allChannelsInfo, eclNodeInformation, eclPageSettings, onchainBalance, peers } from '../../../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../../../shared/pipes/app.pipe';\n\n@Component({\n selector: 'rtl-ecl-channel-open-table',\n templateUrl: './channel-open-table.component.html',\n styleUrls: ['./channel-open-table.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Channels') }\n ]\n})\nexport class ECLChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestroy {\n\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;\n public faEye = faEye;\n public faEyeSlash = faEyeSlash;\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterBy = 'all';\n public colWidth = '20rem';\n public PAGE_ID = 'peers_channels';\n public tableSetting: TableSetting = { tableId: 'open_channels', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };\n public activeChannels: Channel[];\n public totalBalance = 0;\n public displayedColumns: any[] = [];\n public channels: any = new MatTableDataSource([]);\n public myChanPolicy: any = {};\n public information: GetInfo = {};\n public numPeers = -1;\n public feeRateTypes = FEE_RATE_TYPES;\n public selFilter = '';\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService, private router: Router, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n this.selFilter = this.router.getCurrentNavigation()?.extras?.state?.filter ? this.router.getCurrentNavigation()?.extras?.state?.filter : '';\n }\n\n ngOnInit() {\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.unshift('announceChannel');\n this.displayedColumns.push('actions');\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n this.store.select(allChannelsInfo).pipe(takeUntil(this.unSubs[1])).\n subscribe((allChannelsSelector: ({ activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], lightningBalance: LightningBalance, channelsStatus: ChannelsStatus, apiCallStatus: ApiCallStatusPayload })) => {\n this.errorMessage = '';\n this.apiCallStatus = allChannelsSelector.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n this.activeChannels = allChannelsSelector.activeChannels;\n if (this.activeChannels.length > 0 && this.sort && this.paginator && this.displayedColumns.length > 0) {\n this.loadChannelsTable();\n }\n this.logger.info(allChannelsSelector);\n });\n this.store.select(eclNodeInformation).pipe(takeUntil(this.unSubs[2])).\n subscribe((nodeInfo: any) => {\n this.information = nodeInfo;\n });\n this.store.select(peers).pipe(takeUntil(this.unSubs[3])).\n subscribe((peersSelector: { peers: Peer[], apiCallStatus: ApiCallStatusPayload }) => {\n this.numPeers = (peersSelector.peers && peersSelector.peers.length) ? peersSelector.peers.length : 0;\n });\n this.store.select(onchainBalance).pipe(takeUntil(this.unSubs[4])).\n subscribe((ocBalSelector: { onchainBalance: OnChainBalance, apiCallStatus: ApiCallStatusPayload }) => {\n this.totalBalance = ocBalSelector.onchainBalance.total || 0;\n });\n }\n\n ngAfterViewInit() {\n if (this.activeChannels.length > 0 && this.sort && this.paginator && this.displayedColumns.length > 0) {\n this.loadChannelsTable();\n }\n }\n\n onChannelUpdate(channelToUpdate: Channel) {\n if (channelToUpdate !== 'all' && channelToUpdate.state !== 'NORMAL') {\n return;\n }\n const titleMsg = channelToUpdate === 'all' ? 'Update fee policy for all channels' :\n ('Update fee policy for Channel: ' + ((!channelToUpdate.alias && !channelToUpdate.shortChannelId) ? channelToUpdate.channelId :\n (channelToUpdate.alias && channelToUpdate.shortChannelId) ? channelToUpdate.alias + ' (' + channelToUpdate.shortChannelId + ')' :\n channelToUpdate.alias ? channelToUpdate.alias : channelToUpdate.shortChannelId));\n const confirmationMsg = [];\n this.store.dispatch(openConfirmation({\n payload: {\n data: {\n type: AlertTypeEnum.CONFIRM,\n alertTitle: 'Update Fee Policy',\n noBtnText: 'Cancel',\n yesBtnText: 'Update',\n message: confirmationMsg,\n titleMessage: titleMsg,\n flgShowInput: true,\n getInputs: [\n { placeholder: 'Base Fee (mSats)', inputType: DataTypeEnum.NUMBER, inputValue: channelToUpdate && typeof channelToUpdate.feeBaseMsat !== 'undefined' ? channelToUpdate.feeBaseMsat : 1000, step: 100, width: 48 },\n { placeholder: 'Fee Rate (mili mSats)', inputType: DataTypeEnum.NUMBER, inputValue: channelToUpdate && typeof channelToUpdate.feeProportionalMillionths !== 'undefined' ? channelToUpdate.feeProportionalMillionths : 100, min: 1, width: 48, hintFunction: this.percentHintFunction }\n ]\n }\n }\n }));\n this.rtlEffects.closeConfirm.\n pipe(takeUntil(this.unSubs[5])).\n subscribe((confirmRes) => {\n if (confirmRes) {\n const base_fee = confirmRes[0].inputValue;\n const fee_rate = confirmRes[1].inputValue;\n let updateRequestPayload: any = null;\n if (this.commonService.isVersionCompatible(this.information.version, '0.6.2')) {\n let node_ids = '';\n if (channelToUpdate === 'all') {\n this.activeChannels.forEach((channel) => {\n node_ids = node_ids + ',' + channel.nodeId;\n });\n node_ids = node_ids.substring(1);\n updateRequestPayload = { baseFeeMsat: base_fee, feeRate: fee_rate, nodeIds: node_ids };\n } else {\n updateRequestPayload = { baseFeeMsat: base_fee, feeRate: fee_rate, nodeId: channelToUpdate.nodeId };\n }\n } else {\n let channel_ids = '';\n if (channelToUpdate === 'all') {\n this.activeChannels.forEach((channel) => {\n channel_ids = channel_ids + ',' + channel.channelId;\n });\n channel_ids = channel_ids.substring(1);\n updateRequestPayload = { baseFeeMsat: base_fee, feeRate: fee_rate, channelIds: channel_ids };\n } else {\n updateRequestPayload = { baseFeeMsat: base_fee, feeRate: fee_rate, channelId: channelToUpdate.channelId };\n }\n }\n this.store.dispatch(updateChannel({ payload: updateRequestPayload }));\n }\n });\n this.applyFilter();\n }\n\n percentHintFunction(feeProportionalMillionths) {\n return (feeProportionalMillionths / 10000).toString() + '%';\n }\n\n onChannelClose(channelToClose: Channel, forceClose: boolean) {\n const alertTitle = (forceClose) ? 'Force Close Channel' : 'Close Channel';\n const yesBtnText = (forceClose) ? 'Force Close' : 'Close Channel';\n const titleMessage = (forceClose) ?\n ('Force closing channel: ' + ((!channelToClose.alias && !channelToClose.shortChannelId) ? channelToClose.channelId :\n (channelToClose.alias && channelToClose.shortChannelId) ? channelToClose.alias + ' (' + channelToClose.shortChannelId + ')' :\n channelToClose.alias ? channelToClose.alias : channelToClose.shortChannelId)) : ('Closing channel: ' +\n ((!channelToClose.alias && !channelToClose.shortChannelId) ? channelToClose.channelId :\n (channelToClose.alias && channelToClose.shortChannelId) ? channelToClose.alias + ' (' + channelToClose.shortChannelId + ')' :\n channelToClose.alias ? channelToClose.alias : channelToClose.shortChannelId));\n this.store.dispatch(openConfirmation({\n payload: {\n data: {\n type: AlertTypeEnum.CONFIRM,\n alertTitle: alertTitle,\n titleMessage: titleMessage,\n noBtnText: 'Cancel',\n yesBtnText: yesBtnText\n }\n }\n }));\n this.rtlEffects.closeConfirm.\n pipe(takeUntil(this.unSubs[6])).\n subscribe((confirmRes) => {\n if (confirmRes) {\n this.store.dispatch(closeChannel({ payload: { channelId: channelToClose.channelId, force: forceClose } }));\n }\n });\n }\n\n onChannelClick(selChannel: Channel, event: any) {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n channel: selChannel,\n channelsType: 'open',\n component: ECLChannelInformationComponent\n }\n }\n }));\n }\n\n applyFilter() {\n this.channels.filter = this.selFilter.trim().toLowerCase();\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column, '_') : column === 'announceChannel' ? 'Private' : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.channels.filterPredicate = (rowData: Channel, fltr: string) => {\n let rowToFilter = '';\n switch (this.selFilterBy) {\n case 'all':\n rowToFilter = JSON.stringify(rowData).toLowerCase();\n break;\n\n case 'announceChannel':\n rowToFilter = rowData?.announceChannel ? 'public' : 'private';\n break;\n\n default:\n rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();\n break;\n }\n return rowToFilter.includes(fltr);\n };\n }\n\n loadChannelsTable() {\n this.channels = new MatTableDataSource<Channel>([...this.activeChannels]);\n this.channels.sort = this.sort;\n this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);\n this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.channels.paginator = this.paginator;\n this.setFilterPredicate();\n this.applyFilter();\n this.logger.info(this.channels);\n }\n\n onDownloadCSV() {\n if (this.channels.data && this.channels.data.length > 0) {\n this.commonService.downloadFile(this.channels.data, 'ActiveChannels');\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" class=\"padding-gap\">\n <div fxLayout=\"column\" fxLayout.gt-xs=\"row\" fxLayoutAlign.gt-xs=\"start center\" fxLayoutAlign=\"start stretch\" class=\"page-sub-title-container\">\n <div fxFlex=\"70\"></div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput name=\"filter\" placeholder=\"Filter\" [(ngModel)]=\"selFilter\" (input)=\"applyFilter()\" (keyup)=\"applyFilter()\">\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #table mat-table fxFlex=\"100\" matSort [dataSource]=\"channels\" [ngClass]=\"{'error-border': errorMessage !== ''}\">\n <ng-container matColumnDef=\"announceChannel\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header matTooltip=\"Private\"></th>\n <td *matCellDef=\"let channel\" mat-cell>\n <span *ngIf=\"!channel?.announceChannel\" class=\"mr-1\" matTooltip=\"Private\" matTooltipPosition=\"right\"><fa-icon [icon]=\"faEyeSlash\"></fa-icon></span>\n <span *ngIf=\"channel?.announceChannel\" class=\"mr-1\" matTooltip=\"Public\" matTooltipPosition=\"right\"><fa-icon [icon]=\"faEye\"></fa-icon></span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"state\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>State</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.state | titlecase}}</td>\n </ng-container>\n <ng-container matColumnDef=\"channelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Channel ID</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{channel?.channelId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"alias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Alias</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.alias}}</td>\n </ng-container>\n <ng-container matColumnDef=\"nodeId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Node ID</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{channel?.nodeId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"isFunder\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Funder</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.isFunder ? 'Yes' : 'No'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"buried\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Buried</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.buried ? 'Yes' : 'No'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"toLocal\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Local Balance (Sats)</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.toLocal | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"toRemote\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Remote Balance (Sats)</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.toRemote | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"feeRatePerKw\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Fee/KW</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.feeRatePerKw | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onDownloadCSV()\">Download CSV</mat-option>\n </mat-select>\n </div>\n </th> \n <td *matCellDef=\"let channel\" mat-cell fxLayoutAlign=\"end center\">\n <button mat-stroked-button color=\"primary\" type=\"button\" tabindex=\"4\" class=\"table-actions-button\" (click)=\"onChannelClick(channel, $event)\">View Info</button>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"no_channel\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No pending channel available.</p>\n <p *ngIf=\"(!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting pending channels...</p>\n <p *ngIf=\"(!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_channel']\" mat-footer-row [ngClass]=\"{'display-none': channels?.data && channels?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div>\n <mat-paginator class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild, AfterViewInit } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\n\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\nimport { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';\n\nimport { Channel, ChannelsStatus, GetInfo, LightningBalance, OnChainBalance, Peer } from '../../../../../shared/models/eclModels';\nimport { 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';\nimport { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';\nimport { ECLChannelInformationComponent } from '../../channel-information-modal/channel-information.component';\nimport { LoggerService } from '../../../../../shared/services/logger.service';\nimport { CommonService } from '../../../../../shared/services/common.service';\n\nimport { openAlert } from '../../../../../store/rtl.actions';\nimport { RTLState } from '../../../../../store/rtl.state';\nimport { allChannelsInfo, eclNodeInformation, eclPageSettings, onchainBalance, peers } from '../../../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../../../shared/pipes/app.pipe';\n\n\n@Component({\n selector: 'rtl-ecl-channel-pending-table',\n templateUrl: './channel-pending-table.component.html',\n styleUrls: ['./channel-pending-table.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Channels') }\n ]\n})\nexport class ECLChannelPendingTableComponent implements OnInit, AfterViewInit, OnDestroy {\n\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;\n public faEye = faEye;\n public faEyeSlash = faEyeSlash;\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterBy = 'all';\n public colWidth = '20rem';\n public PAGE_ID = 'peers_channels';\n public tableSetting: TableSetting = { tableId: 'pending_channels', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };\n public pendingChannels: Channel[];\n public totalBalance = 0;\n public displayedColumns: any[] = [];\n public channels: any = new MatTableDataSource([]);\n public myChanPolicy: any = {};\n public information: GetInfo = {};\n public numPeers = -1;\n public feeRateTypes = FEE_RATE_TYPES;\n public selFilter = '';\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.unshift('announceChannel');\n this.displayedColumns.push('actions');\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n this.store.select(allChannelsInfo).pipe(takeUntil(this.unSubs[1])).\n subscribe((allChannelsSelector: ({ activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], lightningBalance: LightningBalance, channelsStatus: ChannelsStatus, apiCallStatus: ApiCallStatusPayload })) => {\n this.errorMessage = '';\n this.apiCallStatus = allChannelsSelector.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n this.pendingChannels = allChannelsSelector.pendingChannels;\n this.loadChannelsTable();\n this.logger.info(allChannelsSelector);\n });\n this.store.select(eclNodeInformation).pipe(takeUntil(this.unSubs[2])).\n subscribe((nodeInfo: GetInfo) => {\n this.information = nodeInfo;\n });\n this.store.select(peers).pipe(takeUntil(this.unSubs[3])).\n subscribe((peersSelector: { peers: Peer[], apiCallStatus: ApiCallStatusPayload }) => {\n this.numPeers = (peersSelector.peers && peersSelector.peers.length) ? peersSelector.peers.length : 0;\n });\n this.store.select(onchainBalance).pipe(takeUntil(this.unSubs[4])).\n subscribe((oCBalanceSelector: { onchainBalance: OnChainBalance, apiCallStatus: ApiCallStatusPayload }) => {\n this.totalBalance = oCBalanceSelector.onchainBalance.total || 0;\n });\n }\n\n ngAfterViewInit() {\n if (this.pendingChannels.length > 0) {\n this.loadChannelsTable();\n }\n }\n\n onChannelClick(selChannel: Channel, event: any) {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n channel: selChannel,\n channelsType: 'pending',\n component: ECLChannelInformationComponent\n }\n }\n }));\n }\n\n applyFilter() {\n this.channels.filter = this.selFilter.trim().toLowerCase();\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column, '_') : column === 'announceChannel' ? 'Private' : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.channels.filterPredicate = (rowData: Channel, fltr: string) => {\n let rowToFilter = '';\n switch (this.selFilterBy) {\n case 'all':\n rowToFilter = JSON.stringify(rowData).toLowerCase();\n break;\n\n case 'announceChannel':\n rowToFilter = rowData?.announceChannel ? 'public' : 'private';\n break;\n\n default:\n rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();\n break;\n }\n return rowToFilter.includes(fltr);\n };\n }\n\n loadChannelsTable() {\n this.channels = new MatTableDataSource<Channel>([...this.pendingChannels]);\n this.channels.sort = this.sort;\n this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);\n this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.channels.paginator = this.paginator;\n this.setFilterPredicate();\n this.applyFilter();\n this.logger.info(this.channels);\n }\n\n onDownloadCSV() {\n if (this.channels.data && this.channels.data.length > 0) {\n this.commonService.downloadFile(this.channels.data, 'PendingChannels');\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"row\">\n <div fxFlex=\"100\">\n <mat-card-header fxLayout=\"row\" fxLayoutAlign=\"space-between center\" class=\"modal-info-header\">\n <div fxFlex=\"95\" fxLayoutAlign=\"start start\">\n <span class=\"page-title\">Connect to a new peer</span>\n </div>\n <button tabindex=\"8\" fxFlex=\"5\" fxLayoutAlign=\"center\" class=\"btn-close-x p-0\" mat-button (click)=\"onClose()\">X</button>\n </mat-card-header> \n <mat-card-content class=\"padding-gap-x-large\">\n <div fxLayout=\"column\">\n <mat-vertical-stepper #stepper [linear]=\"true\" (selectionChange)=\"stepSelectionChanged($event)\">\n <mat-step [stepControl]=\"peerFormGroup\" [editable]=\"flgEditable\">\n <form fxLayout=\"column\" fxLayout.gt-sm=\"row wrap\" fxLayoutAlign=\"start\" fxLayoutAlign.gt-sm=\"space-between\" class=\"my-1\" [formGroup]=\"peerFormGroup\">\n <ng-template matStepLabel>{{peerFormLabel}}</ng-template> \n <mat-form-field fxFlex=\"100\">\n <input autoFocus matInput placeholder=\"Lightning Address (pubkey OR pubkey@ip:port)\" formControlName=\"peerAddress\" tabindex=\"1\" required>\n <mat-error *ngIf=\"peerFormGroup.controls.peerAddress.errors?.required\">Address is required.</mat-error>\n </mat-form-field>\n <div *ngIf=\"peerConnectionError !== ''\" fxFlex=\"100\" class=\"alert alert-danger mt-1\">\n <fa-icon class=\"mr-1 alert-icon\" [icon]=\"faExclamationTriangle\"></fa-icon>\n <span>{{peerConnectionError}}</span>\n </div>\n <div class=\"mt-2\" fxLayout=\"row\" fxLayoutAlign=\"start center\" fxFlex=\"100\">\n <button mat-button color=\"primary\" tabindex=\"3\" type=\"button\" (click)=\"onConnectPeer()\">{{peerConnectionError !== '' ? 'Retry' : 'Add Peer'}}</button>\n </div>\n </form>\n </mat-step>\n <mat-step [stepControl]=\"channelFormGroup\" [editable]=\"flgEditable\">\n <form fxLayout=\"column\" fxLayout.gt-sm=\"row wrap\" fxLayoutAlign=\"start\" fxLayoutAlign.gt-sm=\"space-between\" class=\"mb-1\" [formGroup]=\"channelFormGroup\">\n <ng-template matStepLabel disabled=\"true\">{{channelFormLabel}}</ng-template>\n <div fxLayout=\"column\" fxLayout.gt-sm=\"row wrap\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between center\">\n <mat-form-field fxFlex=\"30\" fxLayoutAlign=\"start end\">\n <input matInput autoFocus formControlName=\"fundingAmount\" placeholder=\"Amount\" type=\"number\" tabindex=\"1\" required [step]=\"1000\">\n <mat-hint>Remaining Bal: {{totalBalance - ((channelFormGroup.controls.fundingAmount.value) ? channelFormGroup.controls.fundingAmount.value : 0)}}</mat-hint>\n <span matSuffix> Sats </span>\n <mat-error *ngIf=\"channelFormGroup.controls.fundingAmount.errors?.required\">Amount is required.</mat-error>\n <mat-error *ngIf=\"channelFormGroup.controls.fundingAmount.errors?.min\">Amount must be a positive number.</mat-error>\n <mat-error *ngIf=\"channelFormGroup.controls.fundingAmount.errors?.max\">Amount must be less than or equal to {{totalBalance}}.</mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"30\">\n <input matInput formControlName=\"feeRate\" placeholder=\"Fee (Sats/vByte)\" type=\"number\" name=\"feeRate\" tabindex=\"7\" [step]=\"1\" [min]=\"0\">\n </mat-form-field>\n <div fxFlex=\"35\" fxLayoutAlign=\"start center\">\n <mat-slide-toggle tabindex=\"2\" color=\"primary\" formControlName=\"isPrivate\" name=\"isPrivate\">Private Channel</mat-slide-toggle>\n </div>\n </div>\n </div>\n <div *ngIf=\"channelConnectionError !== ''\" fxFlex=\"100\" class=\"alert alert-danger mt-1\">\n <fa-icon class=\"mr-1 alert-icon\" [icon]=\"faExclamationTriangle\"></fa-icon>\n <span>{{channelConnectionError}}</span>\n </div>\n <div class=\"mt-2\" fxLayout=\"row\" fxLayoutAlign=\"start center\" fxFlex=\"100\">\n <button mat-button color=\"primary\" tabindex=\"8\" type=\"button\" (click)=\"onOpenChannel()\">{{channelConnectionError !== '' ? 'Retry' : 'Open Channel'}}</button>\n </div>\n </form>\n </mat-step>\n </mat-vertical-stepper>\n <div fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"end center\"> \n <button mat-button color=\"primary\" tabindex=\"12\" type=\"button\" default (click)=\"onClose()\">{{newlyAddedPeer?.nodeId ? 'Do It Later' : 'Close'}}</button>\n </div>\n </div>\n </mat-card-content>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild, Inject } from '@angular/core';\nimport { UntypedFormGroup, UntypedFormBuilder, Validators } from '@angular/forms';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { Actions } from '@ngrx/effects';\nimport { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';\nimport { MatStepper } from '@angular/material/stepper';\nimport { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';\n\nimport { Peer } from '../../../shared/models/eclModels';\nimport { APICallStatusEnum, ECLActions } from '../../../shared/services/consts-enums-functions';\nimport { ECLOpenChannelAlert } from '../../../shared/models/alertData';\nimport { LoggerService } from '../../../shared/services/logger.service';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { saveNewChannel, saveNewPeer } from '../../store/ecl.actions';\nimport { eclNodeSettings } from '../../store/ecl.selector';\nimport { SelNodeChild } from '../../../shared/models/RTLconfig';\n\n@Component({\n selector: 'rtl-ecl-connect-peer',\n templateUrl: './connect-peer.component.html',\n styleUrls: ['./connect-peer.component.scss']\n})\nexport class ECLConnectPeerComponent implements OnInit, OnDestroy {\n\n @ViewChild('peersForm', { static: false }) form: any;\n @ViewChild('stepper', { static: false }) stepper: MatStepper;\n public faExclamationTriangle = faExclamationTriangle;\n public selNode: SelNodeChild | null = {};\n public peerAddress = '';\n public totalBalance = 0;\n public flgChannelOpened = false;\n public channelOpenStatus = null;\n public newlyAddedPeer: Peer | null = null;\n public flgEditable = true;\n public peerConnectionError = '';\n public channelConnectionError = '';\n public peerFormLabel = 'Peer Details';\n public channelFormLabel = 'Open Channel (Optional)';\n peerFormGroup: UntypedFormGroup;\n channelFormGroup: UntypedFormGroup;\n statusFormGroup: UntypedFormGroup;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];\n\n constructor(public dialogRef: MatDialogRef<ECLConnectPeerComponent>, @Inject(MAT_DIALOG_DATA) public data: ECLOpenChannelAlert, private store: Store<RTLState>, private formBuilder: UntypedFormBuilder, private actions: Actions, private logger: LoggerService) { }\n\n ngOnInit() {\n if (this.data.message) {\n this.totalBalance = this.data.message.balance;\n this.peerAddress = (this.data.message.peer && this.data.message.peer.nodeId && this.data.message.peer.address) ? (this.data.message.peer.nodeId + '@' + this.data.message.peer.address) :\n (this.data.message.peer && this.data.message.peer.nodeId && !this.data.message.peer.address) ? this.data.message.peer.nodeId : '';\n } else {\n this.totalBalance = 0;\n this.peerAddress = '';\n }\n this.peerFormGroup = this.formBuilder.group({\n hiddenAddress: ['', [Validators.required]],\n peerAddress: [this.peerAddress, [Validators.required]]\n });\n this.channelFormGroup = this.formBuilder.group({\n fundingAmount: ['', [Validators.required, Validators.min(1), Validators.max(this.totalBalance)]],\n isPrivate: [!!this.selNode?.unannouncedChannels],\n feeRate: [null],\n hiddenAmount: ['', [Validators.required]]\n });\n this.statusFormGroup = this.formBuilder.group({});\n this.store.select(eclNodeSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((nodeSettings: SelNodeChild | null) => {\n this.selNode = nodeSettings;\n this.channelFormGroup.controls.isPrivate.setValue(!!nodeSettings?.unannouncedChannels);\n });\n this.actions.pipe(\n takeUntil(this.unSubs[1]),\n filter((action) => action.type === ECLActions.NEWLY_ADDED_PEER_ECL || action.type === ECLActions.FETCH_CHANNELS_ECL || action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL)).\n subscribe((action: any) => {\n if (action.type === ECLActions.NEWLY_ADDED_PEER_ECL) {\n this.logger.info(action.payload);\n this.flgEditable = false;\n this.newlyAddedPeer = action.payload.peer;\n this.peerFormGroup.controls.hiddenAddress.setValue(this.peerFormGroup.controls.peerAddress.value);\n this.stepper.next();\n }\n if (action.type === ECLActions.FETCH_CHANNELS_ECL) {\n this.dialogRef.close();\n }\n if (action.type === ECLActions.UPDATE_API_CALL_STATUS_ECL && action.payload.status === APICallStatusEnum.ERROR) {\n if (action.payload.action === 'SaveNewPeer') {\n this.peerConnectionError = action.payload.message;\n } else if (action.payload.action === 'SaveNewChannel') {\n this.channelConnectionError = action.payload.message;\n }\n }\n });\n }\n\n onConnectPeer(): boolean | void {\n if (!this.peerFormGroup.controls.peerAddress.value) {\n return true;\n }\n this.peerConnectionError = '';\n this.store.dispatch(saveNewPeer({ payload: { id: this.peerFormGroup.controls.peerAddress.value } }));\n }\n\n onOpenChannel(): boolean | void {\n if (!this.channelFormGroup.controls.fundingAmount.value || ((this.totalBalance - this.channelFormGroup.controls.fundingAmount.value) < 0)) {\n return true;\n }\n this.channelConnectionError = '';\n this.store.dispatch(saveNewChannel({\n payload: {\n nodeId: this.newlyAddedPeer?.nodeId!, amount: this.channelFormGroup.controls.fundingAmount.value, private: this.channelFormGroup.controls.isPrivate.value, feeRate: this.channelFormGroup.controls.feeRate.value\n }\n }));\n }\n\n onClose() {\n this.dialogRef.close(false);\n }\n\n stepSelectionChanged(event: any) {\n switch (event.selectedIndex) {\n case 0:\n this.peerFormLabel = 'Peer Details';\n this.channelFormLabel = 'Open Channel (Optional)';\n break;\n\n case 1:\n if (this.peerFormGroup.controls.peerAddress.value) {\n this.peerFormLabel = 'Peer Added: ' + (this.newlyAddedPeer?.alias ? this.newlyAddedPeer.alias : this.newlyAddedPeer?.nodeId);\n } else {\n this.peerFormLabel = 'Peer Details';\n }\n this.channelFormLabel = 'Open Channel (Optional)';\n break;\n\n case 2:\n if (this.peerFormGroup.controls.peerAddress.value) {\n this.peerFormLabel = 'Peer Added: ' + (this.newlyAddedPeer?.alias ? this.newlyAddedPeer.alias : this.newlyAddedPeer?.nodeId);\n } else {\n this.peerFormLabel = 'Peer Details';\n }\n if (this.channelFormGroup.controls.fundingAmount.value) {\n this.channelFormLabel = 'Opening Channel for ' + this.channelFormGroup.controls.fundingAmount.value + ' Sats';\n } else {\n this.channelFormLabel = 'Open Channel (Optional)';\n }\n break;\n\n default:\n this.peerFormLabel = 'Peer Details';\n this.channelFormLabel = 'Open Channel (Optional)';\n break;\n }\n if (event.selectedIndex < event.previouslySelectedIndex) {\n if (event.selectedIndex === 0) {\n this.peerFormGroup.controls.hiddenAddress.setValue('');\n } else if (event.selectedIndex === 1) {\n this.channelFormGroup.controls.hiddenAmount.setValue('');\n }\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <form #peersForm=\"ngForm\" fxLayout=\"column\" fxLayoutAlign=\"space-between stretch\" fxLayout.gt-sm=\"row wrap\">\n <button mat-flat-button color=\"primary\" type=\"submit\" tabindex=\"1\" (click)=\"onConnectPeer({})\">Add Peer</button>\n </form>\n <div fxLayout=\"column\">\n <div fxLayout=\"column\" fxLayout.gt-xs=\"row\" fxLayoutAlign.gt-xs=\"start center\" fxLayoutAlign=\"start stretch\" class=\"page-sub-title-container\">\n <div fxFlex=\"70\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faUsers\"></fa-icon>\n <span class=\"page-title\">Peers</span>\n </div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput name=\"filter\" placeholder=\"Filter\" [(ngModel)]=\"selFilter\" (input)=\"applyFilter()\" (keyup)=\"applyFilter()\">\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #table mat-table fxFlex=\"100\" matSort [dataSource]=\"peers\" [ngClass]=\"{'error-border': errorMessage !== ''}\">\n <ng-container matColumnDef=\"state\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\" matTooltip=\"State\"></th>\n <td *matCellDef=\"let peer\" mat-cell>\n <span *ngIf=\"peer.state === 'CONNECTED'\" class=\"dot green\" matTooltip=\"Connected\" matTooltipPosition=\"right\" [ngClass]=\"{'mr-0': screenSize === screenSizeEnum.XS}\"></span>\n <span *ngIf=\"peer.state === 'DISCONNECTED'\" class=\"dot red\" matTooltip=\"Disconnected\" matTooltipPosition=\"right\" [ngClass]=\"{'mr-0': screenSize === screenSizeEnum.XS}\"></span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"alias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Alias</th>\n <td *matCellDef=\"let peer\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{peer?.alias}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"nodeId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Node ID</th>\n <td *matCellDef=\"let peer\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{peer?.nodeId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"address\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Network Address</th>\n <td *matCellDef=\"let peer\" mat-cell>\n {{peer?.address}}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"channels\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Channels</th>\n <td *matCellDef=\"let peer\" mat-cell>{{peer?.channels}}</td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onDownloadCSV()\">Download CSV</mat-option>\n </mat-select>\n </div>\n </th>\n <td *matCellDef=\"let peer\" mat-cell fxLayoutAlign=\"end center\">\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onPeerClick(peer, $event)\">View Info</mat-option>\n <mat-option (click)=\"onOpenChannel(peer)\">Open Channel</mat-option>\n <mat-option *ngIf=\"peer.state === 'CONNECTED'\" (click)=\"onPeerDetach(peer)\">Disconnect</mat-option>\n <mat-option *ngIf=\"peer.state === 'DISCONNECTED'\" (click)=\"onConnectPeer(peer)\">Reconnect</mat-option>\n </mat-select>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"no_peer\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!peers?.data || peers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No connected peer.</p>\n <p *ngIf=\"(!peers?.data || peers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting peers...</p>\n <p *ngIf=\"(!peers?.data || peers?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_peer']\" mat-footer-row [ngClass]=\"{'display-none': peers?.data && peers?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div>\n <mat-paginator class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n </div>\n</div>\n","import { Component, OnInit, AfterViewInit, OnDestroy, ViewChild } from '@angular/core';\n\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { Actions } from '@ngrx/effects';\nimport { faUsers } from '@fortawesome/free-solid-svg-icons';\n\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\nimport { Peer, GetInfo, OnChainBalance } from '../../../shared/models/eclModels';\nimport { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, ScreenSizeEnum, APICallStatusEnum, ECLActions, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { CommonService } from '../../../shared/services/common.service';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\nimport { ECLOpenChannelComponent } from '../channels/open-channel-modal/open-channel.component';\nimport { ECLConnectPeerComponent } from '../connect-peer/connect-peer.component';\n\nimport { RTLEffects } from '../../../store/rtl.effects';\nimport { RTLState } from '../../../store/rtl.state';\nimport { openAlert, openConfirmation } from '../../../store/rtl.actions';\nimport { disconnectPeer } from '../../store/ecl.actions';\nimport { eclNodeInformation, eclPageSettings, onchainBalance, peers } from '../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../shared/pipes/app.pipe';\n\n@Component({\n selector: 'rtl-ecl-peers',\n templateUrl: './peers.component.html',\n styleUrls: ['./peers.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Peers') }\n ]\n})\nexport class ECLPeersComponent implements OnInit, AfterViewInit, OnDestroy {\n\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterBy = 'all';\n public colWidth = '20rem';\n public PAGE_ID = 'peers_channels';\n public tableSetting: TableSetting = { tableId: 'peers', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };\n public faUsers = faUsers;\n public newlyAddedPeer = '';\n public displayedColumns: any[] = [];\n public peerAddress: string | null = '';\n public peersData: Peer[] = [];\n public peers: any = new MatTableDataSource([]);\n public information: GetInfo = {};\n public availableBalance = 0;\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public selFilter = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private actions: Actions, private commonService: CommonService, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.store.select(eclNodeInformation).pipe(takeUntil(this.unSubs[0])).\n subscribe((nodeInfo: any) => {\n this.information = nodeInfo;\n });\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[1])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.unshift('state');\n this.displayedColumns.push('actions');\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n\n this.store.select(peers).pipe(takeUntil(this.unSubs[2])).\n subscribe((peersSelector: { peers: Peer[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = peersSelector.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n this.peersData = peersSelector.peers;\n this.loadPeersTable(this.peersData);\n this.logger.info(peersSelector);\n });\n this.store.select(onchainBalance).pipe(takeUntil(this.unSubs[3])).\n subscribe((oCBalanceSelector: { onchainBalance: OnChainBalance, apiCallStatus: ApiCallStatusPayload }) => {\n this.availableBalance = oCBalanceSelector.onchainBalance.total || 0;\n });\n this.actions.pipe(takeUntil(this.unSubs[4]), filter((action) => action.type === ECLActions.SET_PEERS_ECL)).\n subscribe((setPeers: any) => {\n this.peerAddress = null;\n });\n }\n\n ngAfterViewInit() {\n if (this.peersData.length > 0) {\n this.loadPeersTable(this.peersData);\n }\n }\n\n onPeerClick(selPeer: Peer, event: any) {\n const reorderedPeer = [\n [{ key: 'nodeId', value: selPeer.nodeId, title: 'Public Key', width: 100 }],\n [{ key: 'address', value: selPeer.address, title: 'Address', width: 50 },\n { key: 'alias', value: selPeer.alias, title: 'Alias', width: 50 }],\n [{ key: 'state', value: this.commonService.titleCase(selPeer.state || ''), title: 'State', width: 50 },\n { key: 'channels', value: selPeer.channels, title: 'Channels', width: 50 }]\n ];\n this.store.dispatch(openAlert({\n payload: {\n data: {\n type: AlertTypeEnum.INFORMATION,\n alertTitle: 'Peer Information',\n showQRName: 'Public Key',\n showQRField: selPeer.nodeId,\n message: reorderedPeer\n }\n }\n }));\n }\n\n onConnectPeer(selPeer: Peer) {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n message: {\n peer: selPeer.nodeId ? selPeer : null,\n information: this.information,\n balance: this.availableBalance\n },\n component: ECLConnectPeerComponent\n }\n }\n }));\n }\n\n onOpenChannel(peerToAddChannel: Peer) {\n const peerToAddChannelMessage = {\n peer: peerToAddChannel,\n information: this.information,\n balance: this.availableBalance\n };\n this.store.dispatch(openAlert({\n payload: {\n data: {\n alertTitle: 'Open Channel',\n message: peerToAddChannelMessage,\n newlyAdded: false,\n component: ECLOpenChannelComponent\n }\n }\n }));\n }\n\n onPeerDetach(peerToDetach: Peer) {\n if (peerToDetach && peerToDetach.channels && peerToDetach.channels > 0) {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n type: AlertTypeEnum.ERROR,\n alertTitle: 'Disconnect Not Allowed',\n titleMessage: 'Channel active with this peer.'\n }\n }\n }));\n } else {\n this.store.dispatch(openConfirmation({\n payload: {\n data: {\n type: AlertTypeEnum.CONFIRM,\n alertTitle: 'Disconnect Peer',\n titleMessage: 'Disconnect peer: ' + ((peerToDetach.alias) ? peerToDetach.alias : peerToDetach.nodeId),\n noBtnText: 'Cancel',\n yesBtnText: 'Disconnect'\n }\n }\n }));\n }\n this.rtlEffects.closeConfirm.\n pipe(takeUntil(this.unSubs[5])).\n subscribe((confirmRes) => {\n if (confirmRes) {\n this.store.dispatch(disconnectPeer({ payload: { nodeId: (peerToDetach.nodeId || '') } }));\n }\n });\n }\n\n applyFilter() {\n this.peers.filter = this.selFilter.trim().toLowerCase();\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column, '_') : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.peers.filterPredicate = (rowData: Peer, fltr: string) => {\n let rowToFilter = '';\n switch (this.selFilterBy) {\n case 'all':\n rowToFilter = JSON.stringify(rowData).toLowerCase();\n break;\n\n case 'state':\n rowToFilter = rowData?.state?.toLowerCase() || '';\n break;\n\n default:\n rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();\n break;\n }\n return this.selFilterBy === 'state' ? rowToFilter.indexOf(fltr) === 0 : rowToFilter.includes(fltr);\n };\n }\n\n loadPeersTable(peers: Peer[]) {\n this.peers = (peers) ? new MatTableDataSource<Peer>([...peers]) : new MatTableDataSource([]);\n this.peers.sort = this.sort;\n this.peers.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);\n this.peers.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.peers.paginator = this.paginator;\n this.setFilterPredicate();\n this.applyFilter();\n }\n\n onDownloadCSV() {\n if (this.peers.data && this.peers.data.length > 0) {\n this.commonService.downloadFile(this.peers.data, 'Peers');\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxFlex=\"100\">\n <form #queryRoutesForm=\"ngForm\" fxLayout=\"column\" fxLayoutAlign=\"space-between stretch\" fxLayout.gt-sm=\"row wrap\" (ngSubmit)=\"queryRoutesForm.form.valid && onQueryRoutes()\">\n <div fxFlex=\"100\" class=\"alert alert-warn\">\n <fa-icon class=\"mr-1 alert-icon\" [icon]=\"faExclamationTriangle\"></fa-icon>\n <span>The actual routing fee on a payment can be different from the fee shown on query routes.</span>\n </div>\n <mat-form-field fxFlex=\"69\" fxLayoutAlign=\"start end\">\n <input #destPubkey=\"ngModel\" matInput placeholder=\"Destination Node ID\" name=\"nodeId\" tabindex=\"1\" required [(ngModel)]=\"nodeId\">\n <mat-error *ngIf=\"!nodeId\">Destination Node ID is required.</mat-error>\n </mat-form-field>\n <mat-form-field fxFlex=\"29\" fxLayoutAlign=\"start end\">\n <input matInput placeholder=\"Amount (Sats)\" name=\"amount\" tabindex=\"2\" type=\"number\" required [step]=\"1000\" [min]=\"0\" [(ngModel)]=\"amount\">\n <mat-error *ngIf=\"!amount\">Amount is required.</mat-error>\n </mat-form-field>\n <div fxLayout=\"row\" class=\"mt-1\">\n <button class=\"mr-1\" mat-stroked-button color=\"primary\" tabindex=\"3\" type=\"reset\" (click)=\"resetData()\">Clear</button>\n <button mat-flat-button color=\"primary\" type=\"submit\" tabindex=\"4\">Query Route</button>\n </div>\n </form>\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" class=\"page-sub-title-container mt-2 mb-1\">\n <div fxFlex=\"70\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faRoute\"></fa-icon>\n <span class=\"page-title\">Transaction Route</span>\n </div>\n </div>\n <mat-progress-bar *ngIf=\"flgLoading[0]===true\" mode=\"indeterminate\"></mat-progress-bar>\n <div fxLayout=\"row\" fxFlex=\"100\" class=\"padding-gap-x\" fxLayoutAlign=\"start start\">\n <div fxLayout=\"column\" fxFlex=\"100\">\n <div *ngFor=\"let qRoute of allQRoutes; index as i\" fxFlex=\"100\">\n <mat-expansion-panel class=\"flat-expansion-panel help-expansion mb-2px\">\n <mat-expansion-panel-header>\n <mat-panel-title fxLayout=\"row\" fxLayoutAlign=\"space-between start\">\n <span fxFlex=\"50\" fxLayoutAlign=\"start start\">Route {{i+1}}</span>\n <span fxFlex=\"50\" fxLayoutAlign=\"end end\">{{(qRoute.amount/1000) | number}}</span>\n </mat-panel-title>\n </mat-expansion-panel-header>\n <mat-panel-description fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <div class=\"table-container mb-2\" fxLayout=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" [perfectScrollbar]>\n <table #table[i] mat-table [dataSource]=\"qrHops[i]\" [ngClass]=\"{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}\">\n <ng-container matColumnDef=\"alias\">\n <th *matHeaderCellDef mat-header-cell> Alias</th>\n <td *matCellDef=\"let hop\" mat-cell>\n <span fxLayout=\"row\" class=\"ellipsis-parent\" [ngStyle]=\"{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}\">\n <span class=\"ellipsis-child\">{{hop?.alias}}</span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"nodeId\">\n <th *matHeaderCellDef mat-header-cell> ID</th>\n <td *matCellDef=\"let hop\" mat-cell>\n <span fxLayout=\"row\" class=\"ellipsis-parent\" [ngStyle]=\"{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}\">\n <span class=\"ellipsis-child\">{{hop?.nodeId}}</span>\n </span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">Actions</div> \n </th>\n <td *matCellDef=\"let hop\" mat-cell fxLayoutAlign=\"end center\">\n <button mat-stroked-button color=\"primary\" type=\"button\" tabindex=\"4\" class=\"table-actions-button\" (click)=\"onHopClick(hop)\">View Info</button>\n </td>\n </ng-container>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div> \n </mat-panel-description>\n </mat-expansion-panel>\n </div>\n </div>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { faRoute, faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';\nimport { MatTableDataSource } from '@angular/material/table';\n\nimport { AlertTypeEnum, DataTypeEnum, ScreenSizeEnum } from '../../../shared/services/consts-enums-functions';\nimport { QueryRoutes, RouteNode } from '../../../shared/models/eclModels';\nimport { CommonService } from '../../../shared/services/common.service';\n\nimport { ECLEffects } from '../../store/ecl.effects';\nimport { RTLState } from '../../../store/rtl.state';\nimport { openAlert } from '../../../store/rtl.actions';\nimport { getQueryRoutes } from '../../store/ecl.actions';\n\n@Component({\n selector: 'rtl-ecl-query-routes',\n templateUrl: './query-routes.component.html',\n styleUrls: ['./query-routes.component.scss']\n})\nexport class ECLQueryRoutesComponent implements OnInit, OnDestroy {\n\n @ViewChild('queryRoutesForm', { static: true }) form: any;\n public allQRoutes = [];\n public nodeId = '';\n public amount = 0;\n public qrHops: Array<any> = [];\n public displayedColumns = ['alias', 'nodeId', 'actions'];\n public flgLoading: Array<Boolean | 'error'> = [false]; // 0: peers\n public faRoute = faRoute;\n public faExclamationTriangle = faExclamationTriangle;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];\n\n constructor(private store: Store<RTLState>, private eclEffects: ECLEffects, private commonService: CommonService) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.qrHops[0] = new MatTableDataSource([]);\n this.qrHops[0].data = [];\n this.eclEffects.setQueryRoutes.pipe(takeUntil(this.unSubs[1])).subscribe((queryRoute: any) => {\n if (queryRoute && queryRoute.routes && queryRoute.routes.length) {\n this.flgLoading[0] = false;\n this.allQRoutes = queryRoute.routes;\n this.allQRoutes.forEach((route: any, i) => {\n this.qrHops[i] = new MatTableDataSource<QueryRoutes>([...route.nodeIds]);\n });\n } else {\n this.flgLoading[0] = 'error';\n this.allQRoutes = [];\n this.qrHops = [];\n }\n });\n }\n\n onQueryRoutes(): boolean | void {\n if (!this.nodeId || !this.amount) {\n return true;\n }\n this.qrHops = [];\n this.flgLoading[0] = true;\n this.store.dispatch(getQueryRoutes({ payload: { nodeId: this.nodeId, amount: this.amount * 1000 } }));\n }\n\n resetData() {\n this.allQRoutes = [];\n this.nodeId = '';\n this.amount = 0;\n this.flgLoading[0] = false;\n this.qrHops = [];\n this.form.resetForm();\n }\n\n onHopClick(selHop: RouteNode) {\n const reorderedHop = [\n [{ key: 'alias', value: selHop.alias, title: 'Alias', width: 100, type: DataTypeEnum.STRING }],\n [{ key: 'nodeId', value: selHop.nodeId, title: 'Node ID', width: 100, type: DataTypeEnum.STRING }]\n ];\n this.store.dispatch(openAlert({\n payload: {\n data: {\n type: AlertTypeEnum.INFORMATION,\n alertTitle: 'Route Information',\n message: reorderedHop\n }\n }\n }));\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" class=\"padding-gap\">\n <div fxLayout=\"column\" fxLayout.gt-xs=\"row\" fxLayoutAlign.gt-xs=\"start center\" fxLayoutAlign=\"start stretch\" class=\"page-sub-title-container\">\n <div fxFlex=\"70\"></div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput name=\"filter\" placeholder=\"Filter\" [(ngModel)]=\"selFilter\" (input)=\"applyFilter()\" (keyup)=\"applyFilter()\">\n </mat-form-field>\n </div>\n </div>\n <div fxLayout=\"column\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #table mat-table fxFlex=\"100\" matSort [dataSource]=\"channels\" [ngClass]=\"{'error-border': errorMessage !== ''}\">\n <ng-container matColumnDef=\"announceChannel\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header matTooltip=\"Private\"></th>\n <td *matCellDef=\"let channel\" mat-cell>\n <span *ngIf=\"!channel.announceChannel\" class=\"mr-1\" matTooltip=\"Private\" matTooltipPosition=\"right\"><fa-icon [icon]=\"faEyeSlash\"></fa-icon></span>\n <span *ngIf=\"channel.announceChannel\" class=\"mr-1\" matTooltip=\"Public\" matTooltipPosition=\"right\"><fa-icon [icon]=\"faEye\"></fa-icon></span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"state\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>State</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.state | titlecase}}</td>\n </ng-container>\n <ng-container matColumnDef=\"shortChannelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Short Channel ID</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.shortChannelId}}</td>\n </ng-container>\n <ng-container matColumnDef=\"channelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Channel ID</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{channel?.channelId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"alias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Alias</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{channel.alias}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"nodeId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Node ID</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{channel?.nodeId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"isFunder\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Funder</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.isFunder ? 'Yes' : 'No'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"buried\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Buried</th>\n <td *matCellDef=\"let channel\" mat-cell>{{channel?.buried ? 'Yes' : 'No'}}</td>\n </ng-container>\n <ng-container matColumnDef=\"toLocal\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Local Balance (Sats)</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.toLocal | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"toRemote\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Remote Balance (Sats)</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.toRemote | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"feeRatePerKw\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Local Fee/KW</th>\n <td *matCellDef=\"let channel\" mat-cell><span fxLayoutAlign=\"end center\">\n {{channel?.feeRatePerKw | number:'1.0-0'}} </span></td>\n </ng-container>\n <ng-container matColumnDef=\"balancedness\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Balance Score</th>\n <td *matCellDef=\"let channel\" mat-cell>\n <div fxLayout=\"row\">\n <mat-hint fxFlex=\"100\" fxLayoutAlign=\"center center\" class=\"font-size-80\">{{channel?.balancedness || 0 | number}}</mat-hint>\n </div>\n <mat-progress-bar mode=\"determinate\" value=\"{{channel.toLocal && channel.toLocal > 0 ? ((+channel.toLocal/((+channel.toLocal)+(+channel.toRemote)))*100) : 0}}\"></mat-progress-bar>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onDownloadCSV()\">Download CSV</mat-option>\n </mat-select>\n </div>\n </th> \n <td *matCellDef=\"let channel\" mat-cell fxLayoutAlign=\"end center\">\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"2\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onChannelClick(channel, $event)\">View Info</mat-option>\n <mat-option (click)=\"onChannelClose(channel, true)\">Force Close</mat-option>\n </mat-select>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"no_channel\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No inactive channel available.</p>\n <p *ngIf=\"(!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting inactive channels...</p>\n <p *ngIf=\"(!channels?.data || channels?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_channel']\" mat-footer-row [ngClass]=\"{'display-none': channels?.data && channels?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div>\n <mat-paginator class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n</div>\n","import { Component, OnInit, OnDestroy, ViewChild, AfterViewInit } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\nimport { faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';\n\nimport { Channel, ChannelsStatus, GetInfo, LightningBalance, OnChainBalance, Peer } from '../../../../../shared/models/eclModels';\nimport { 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';\nimport { LoggerService } from '../../../../../shared/services/logger.service';\nimport { CommonService } from '../../../../../shared/services/common.service';\n\nimport { ECLChannelInformationComponent } from '../../channel-information-modal/channel-information.component';\nimport { RTLEffects } from '../../../../../store/rtl.effects';\nimport { ApiCallStatusPayload } from '../../../../../shared/models/apiCallsPayload';\nimport { openAlert, openConfirmation } from '../../../../../store/rtl.actions';\nimport { RTLState } from '../../../../../store/rtl.state';\nimport { closeChannel } from '../../../../store/ecl.actions';\nimport { allChannelsInfo, eclNodeInformation, eclPageSettings, onchainBalance, peers } from '../../../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../../../shared/pipes/app.pipe';\n\n@Component({\n selector: 'rtl-ecl-channel-inactive-table',\n templateUrl: './channel-inactive-table.component.html',\n styleUrls: ['./channel-inactive-table.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Channels') }\n ]\n})\nexport class ECLChannelInactiveTableComponent implements OnInit, AfterViewInit, OnDestroy {\n\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;\n public faEye = faEye;\n public faEyeSlash = faEyeSlash;\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterBy = 'all';\n public colWidth = '20rem';\n public PAGE_ID = 'peers_channels';\n public tableSetting: TableSetting = { tableId: 'inactive_channels', recordsPerPage: PAGE_SIZE, sortBy: 'alias', sortOrder: SortOrderEnum.DESCENDING };\n public inactiveChannels: Channel[];\n public totalBalance = 0;\n public displayedColumns: any[] = [];\n public channels: any = new MatTableDataSource([]);\n public myChanPolicy: any = {};\n public information: GetInfo = {};\n public numPeers = -1;\n public feeRateTypes = FEE_RATE_TYPES;\n public selFilter = '';\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.unshift('announceChannel');\n this.displayedColumns.push('actions');\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n this.store.select(allChannelsInfo).pipe(takeUntil(this.unSubs[1])).\n subscribe((allChannelsSelector: ({ activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], lightningBalance: LightningBalance, channelsStatus: ChannelsStatus, apiCallStatus: ApiCallStatusPayload })) => {\n this.errorMessage = '';\n this.apiCallStatus = allChannelsSelector.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n this.inactiveChannels = allChannelsSelector.inactiveChannels;\n this.loadChannelsTable();\n this.logger.info(allChannelsSelector);\n });\n this.store.select(eclNodeInformation).pipe(takeUntil(this.unSubs[2])).\n subscribe((nodeInfo: GetInfo) => {\n this.information = nodeInfo;\n });\n this.store.select(peers).pipe(takeUntil(this.unSubs[3])).\n subscribe((peersSelector: { peers: Peer[], apiCallStatus: ApiCallStatusPayload }) => {\n this.numPeers = (peersSelector.peers && peersSelector.peers.length) ? peersSelector.peers.length : 0;\n });\n this.store.select(onchainBalance).pipe(takeUntil(this.unSubs[4])).\n subscribe((ocBalSelector: { onchainBalance: OnChainBalance, apiCallStatus: ApiCallStatusPayload }) => {\n this.totalBalance = ocBalSelector.onchainBalance.total || 0;\n });\n }\n\n ngAfterViewInit() {\n if (this.inactiveChannels.length > 0) {\n this.loadChannelsTable();\n }\n }\n\n onChannelClose(channelToClose: Channel, forceClose: boolean) {\n const alertTitle = (forceClose) ? 'Force Close Channel' : 'Close Channel';\n const yesBtnText = (forceClose) ? 'Force Close' : 'Close Channel';\n const titleMessage = (forceClose) ?\n ('Force closing channel: ' + ((!channelToClose.alias && !channelToClose.shortChannelId) ? channelToClose.channelId :\n (channelToClose.alias && channelToClose.shortChannelId) ? channelToClose.alias + ' (' + channelToClose.shortChannelId + ')' :\n channelToClose.alias ? channelToClose.alias : channelToClose.shortChannelId)) :\n ('Closing channel: ' + ((!channelToClose.alias && !channelToClose.shortChannelId) ? channelToClose.channelId :\n (channelToClose.alias && channelToClose.shortChannelId) ? channelToClose.alias + ' (' + channelToClose.shortChannelId + ')' :\n channelToClose.alias ? channelToClose.alias : channelToClose.shortChannelId));\n this.store.dispatch(openConfirmation({\n payload: {\n data: {\n type: AlertTypeEnum.CONFIRM,\n alertTitle: alertTitle,\n titleMessage: titleMessage,\n noBtnText: 'Cancel',\n yesBtnText: yesBtnText\n }\n }\n }));\n this.rtlEffects.closeConfirm.\n pipe(takeUntil(this.unSubs[5])).\n subscribe((confirmRes) => {\n if (confirmRes) {\n this.store.dispatch(closeChannel({ payload: { channelId: channelToClose.channelId || '', force: forceClose } }));\n }\n });\n }\n\n onChannelClick(selChannel: Channel, event: any) {\n this.store.dispatch(openAlert({\n payload: {\n data: {\n channel: selChannel,\n channelsType: 'inactive',\n component: ECLChannelInformationComponent\n }\n }\n }));\n }\n\n applyFilter() {\n this.channels.filter = this.selFilter.trim().toLocaleLowerCase();\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column, '_') : column === 'announceChannel' ? 'Private' : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.channels.filterPredicate = (rowData: Channel, fltr: string) => {\n let rowToFilter = '';\n switch (this.selFilterBy) {\n case 'all':\n rowToFilter = JSON.stringify(rowData).toLowerCase();\n break;\n\n case 'announceChannel':\n rowToFilter = rowData?.announceChannel ? 'public' : 'private';\n break;\n\n default:\n rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();\n break;\n }\n return rowToFilter.includes(fltr);\n };\n }\n\n loadChannelsTable() {\n this.channels = new MatTableDataSource<Channel>([...this.inactiveChannels]);\n this.channels.sort = this.sort;\n this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);\n this.channels.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.channels.paginator = this.paginator;\n this.setFilterPredicate();\n this.applyFilter();\n this.logger.info(this.channels);\n }\n\n onDownloadCSV() {\n if (this.channels.data && this.channels.data.length > 0) {\n this.commonService.downloadFile(this.channels.data, 'InactiveChannels');\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxLayoutAlign=\"start stretch\" class=\"padding-gap-x\">\n <div *ngIf=\"errorMessage !== ''\" class=\"p-2 error-border my-2\">{{errorMessage}}</div>\n <div *ngIf=\"errorMessage === ''\" fxLayout=\"column\" fxLayout.gt-xs=\"row\" fxLayoutAlign.gt-xs=\"start center\" fxLayoutAlign=\"start stretch\" class=\"page-sub-title-container\">\n <div fxFlex=\"70\"></div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput name=\"filter\" placeholder=\"Filter\" [(ngModel)]=\"selFilter\" (input)=\"applyFilter()\" (keyup)=\"applyFilter()\">\n </mat-form-field>\n </div>\n </div>\n <div *ngIf=\"errorMessage === ''\" fxLayout=\"column\" fxLayoutAlign=\"start center\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar> \n <table #table mat-table fxFlex=\"100\" matSort class=\"overflow-auto\" [dataSource]=\"forwardingHistoryEvents\">\n <ng-container matColumnDef=\"type\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\" matTooltip=\"Type (if not payment relayed)\"></th>\n <td *matCellDef=\"let fhEvent\" mat-cell>\n <span *ngIf=\"fhEvent?.type !== 'payment-relayed'\" class=\"dot yellow\" matTooltipPosition=\"right\" matTooltip=\"{{fhEvent?.type | camelcase}}\" [ngClass]=\"{'ml-0': screenSize === screenSizeEnum.XS}\"></span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"timestamp\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Date/Time</th>\n <td *matCellDef=\"let fhEvent\" mat-cell>\n {{fhEvent?.timestamp | date:'dd/MMM/y HH:mm'}}\n </td>\n </ng-container>\n <ng-container matColumnDef=\"fromChannelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>In Channel ID</th>\n <td *matCellDef=\"let fhEvent\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{fhEvent?.fromChannelId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"fromShortChannelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>In Channel Short ID</th>\n <td *matCellDef=\"let fhEvent\" mat-cell>{{fhEvent?.fromShortChannelId}}</td>\n </ng-container>\n <ng-container matColumnDef=\"fromChannelAlias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>In Channel</th>\n <td *matCellDef=\"let fhEvent\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{fhEvent?.fromChannelAlias}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"toChannelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Out Channel ID</th>\n <td *matCellDef=\"let fhEvent\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{fhEvent?.toChannelId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"toShortChannelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Out Channel Short ID</th>\n <td *matCellDef=\"let fhEvent\" mat-cell>{{fhEvent?.toShortChannelId}}</td>\n </ng-container>\n <ng-container matColumnDef=\"toChannelAlias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Out Channel</th>\n <td *matCellDef=\"let fhEvent\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{fhEvent?.toChannelAlias}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"paymentHash\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Payment Hash</th>\n <td *matCellDef=\"let fhEvent\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{fhEvent?.paymentHash}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"amountIn\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Amount In (Sats)</th>\n <td *matCellDef=\"let fhEvent\" mat-cell><span fxLayoutAlign=\"end center\">{{fhEvent?.amountIn | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"amountOut\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Amount Out (Sats)</th>\n <td *matCellDef=\"let fhEvent\" mat-cell><span fxLayoutAlign=\"end center\">{{fhEvent?.amountOut | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"fee\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Fee Earned (Sats)</th>\n <td *matCellDef=\"let fhEvent\" mat-cell><span fxLayoutAlign=\"end center\">{{(fhEvent?.amountIn - fhEvent?.amountOut) | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"actions\">\n <th *matHeaderCellDef mat-header-cell>\n <div class=\"bordered-box table-actions-select\" fxLayoutAlign=\"center center\">\n <mat-select placeholder=\"Actions\" tabindex=\"1\" class=\"mr-0\">\n <mat-select-trigger></mat-select-trigger>\n <mat-option (click)=\"onDownloadCSV()\">Download CSV</mat-option>\n </mat-select>\n </div>\n </th>\n <td *matCellDef=\"let fhEvent\" mat-cell fxLayoutAlign=\"end center\">\n <button mat-stroked-button color=\"primary\" type=\"button\" tabindex=\"4\" class=\"table-actions-button\" (click)=\"onForwardingEventClick(fhEvent,$event)\">View Info</button>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"no_event\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!forwardingHistoryEvents?.data || forwardingHistoryEvents?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No forwarding history available.</p>\n <p *ngIf=\"(!forwardingHistoryEvents?.data || forwardingHistoryEvents?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting forwarding history...</p>\n <p *ngIf=\"(!forwardingHistoryEvents?.data || forwardingHistoryEvents?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_event']\" mat-footer-row [ngClass]=\"{'display-none': forwardingHistoryEvents?.data && forwardingHistoryEvents?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div>\n <mat-paginator *ngIf=\"errorMessage === ''\" class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n</div>\n","import { Component, OnInit, OnChanges, AfterViewInit, ViewChild, OnDestroy, Input, SimpleChanges } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatSort } from '@angular/material/sort';\nimport { MatTableDataSource } from '@angular/material/table';\n\nimport { PaymentRelayed, Payments } from '../../../shared/models/eclModels';\nimport { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { CommonService } from '../../../shared/services/common.service';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { openAlert } from '../../../store/rtl.actions';\nimport { eclPageSettings, payments } from '../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../shared/pipes/app.pipe';\n\n@Component({\n selector: 'rtl-ecl-forwarding-history',\n templateUrl: './forwarding-history.component.html',\n styleUrls: ['./forwarding-history.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Events') }\n ]\n})\nexport class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {\n\n @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;\n @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;\n @Input() pageId = 'routing';\n @Input() tableId = 'forwarding_history';\n @Input() eventsData: PaymentRelayed[] = [];\n @Input() selFilter = '';\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterBy = 'all';\n public colWidth = '20rem';\n public tableSetting: TableSetting = { tableId: 'forwarding_history', recordsPerPage: PAGE_SIZE, sortBy: 'timestamp', sortOrder: SortOrderEnum.DESCENDING };\n public displayedColumns: any[] = [];\n public forwardingHistoryEvents: any = new MatTableDataSource([]);\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting.tableId = this.tableId;\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.pageId)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.pageId)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.unshift('type');\n this.displayedColumns.push('actions');\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n this.store.select(payments).pipe(takeUntil(this.unSubs[1])).\n subscribe((paymentsSelector: { payments: Payments, apiCallStatus: ApiCallStatusPayload }) => {\n if (this.eventsData.length === 0) {\n this.errorMessage = '';\n this.apiCallStatus = paymentsSelector.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n this.eventsData = paymentsSelector.payments && paymentsSelector.payments.relayed ? paymentsSelector.payments.relayed : [];\n if (this.eventsData.length > 0 && this.sort && this.paginator && this.displayedColumns.length > 0) {\n this.loadForwardingEventsTable(this.eventsData);\n }\n this.logger.info(this.eventsData);\n }\n });\n }\n\n ngAfterViewInit() {\n setTimeout(() => {\n if (this.eventsData.length > 0) {\n this.loadForwardingEventsTable(this.eventsData);\n }\n }, 0);\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes.eventsData) {\n this.apiCallStatus = { status: APICallStatusEnum.COMPLETED, action: 'FetchPayments' };\n this.eventsData = changes.eventsData.currentValue;\n if (!changes.eventsData.firstChange) {\n this.loadForwardingEventsTable(this.eventsData);\n }\n }\n if (changes.selFilter && !changes.selFilter.firstChange) {\n this.selFilterBy = 'all';\n this.applyFilter();\n }\n }\n\n onForwardingEventClick(selFEvent: PaymentRelayed, event: any) {\n const reorderedFHEvent = [\n [{ key: 'paymentHash', value: selFEvent.paymentHash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }],\n [{ key: 'timestamp', value: Math.round((selFEvent.timestamp || 0) / 1000), title: 'Date/Time', width: 50, type: DataTypeEnum.DATE_TIME },\n { key: 'fee', value: ((selFEvent.amountIn || 0) - (selFEvent.amountOut || 0)), title: 'Fee Earned (Sats)', width: 50, type: DataTypeEnum.NUMBER }],\n [{ key: 'amountIn', value: selFEvent.amountIn, title: 'Amount In (Sats)', width: 50, type: DataTypeEnum.NUMBER },\n { key: 'amountOut', value: selFEvent.amountOut, title: 'Amount Out (Sats)', width: 50, type: DataTypeEnum.NUMBER }],\n [{ key: 'fromChannelAlias', value: selFEvent.fromChannelAlias, title: 'From Channel Alias', width: 50, type: DataTypeEnum.STRING },\n { key: 'fromShortChannelId', value: selFEvent.fromShortChannelId, title: 'From Short Channel ID', width: 50, type: DataTypeEnum.STRING }],\n [{ key: 'fromChannelId', value: selFEvent.fromChannelId, title: 'From Channel ID', width: 100, type: DataTypeEnum.STRING }],\n [{ key: 'toChannelAlias', value: selFEvent.toChannelAlias, title: 'To Channel Alias', width: 50, type: DataTypeEnum.STRING },\n { key: 'toShortChannelId', value: selFEvent.toShortChannelId, title: 'To Short Channel ID', width: 50, type: DataTypeEnum.STRING }],\n [{ key: 'toChannelId', value: selFEvent.toChannelId, title: 'To Channel ID', width: 100, type: DataTypeEnum.STRING }]\n ];\n if (selFEvent.type !== 'payment-relayed') {\n reorderedFHEvent?.unshift([{ key: 'type', value: this.commonService.camelCase(selFEvent.type), title: 'Relay Type', width: 100, type: DataTypeEnum.STRING }]);\n }\n this.store.dispatch(openAlert({\n payload: {\n data: {\n type: AlertTypeEnum.INFORMATION,\n alertTitle: 'Event Information',\n message: reorderedFHEvent\n }\n }\n }));\n }\n\n applyFilter() {\n if (this.forwardingHistoryEvents) {\n this.forwardingHistoryEvents.filter = this.selFilter.trim().toLowerCase();\n }\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.pageId][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column) : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.forwardingHistoryEvents.filterPredicate = (rowData: PaymentRelayed, fltr: string) => {\n let rowToFilter = '';\n switch (this.selFilterBy) {\n case 'all':\n rowToFilter = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp), 'dd/MMM/y HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();\n break;\n\n case 'timestamp':\n rowToFilter = this.datePipe.transform(new Date((rowData.timestamp || 0)), 'dd/MMM/y HH:mm')?.toLowerCase() || '';\n break;\n\n case 'fee':\n rowToFilter = (rowData.amountIn - rowData.amountOut).toString() || '0';\n break;\n\n default:\n rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();\n break;\n }\n return rowToFilter.includes(fltr);\n };\n }\n\n loadForwardingEventsTable(forwardingEvents: PaymentRelayed[]) {\n this.forwardingHistoryEvents = new MatTableDataSource<PaymentRelayed>([...forwardingEvents]);\n this.forwardingHistoryEvents.sort = this.sort;\n this.forwardingHistoryEvents.sortingDataAccessor = (data: any, sortHeaderId: string) => {\n switch (sortHeaderId) {\n case 'fee':\n return data.amountIn - data.amountOut;\n\n default:\n return (data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null;\n }\n };\n this.forwardingHistoryEvents.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.forwardingHistoryEvents.paginator = this.paginator;\n this.setFilterPredicate();\n this.applyFilter();\n this.logger.info(this.forwardingHistoryEvents);\n }\n\n onDownloadCSV() {\n if (this.forwardingHistoryEvents && this.forwardingHistoryEvents.data && this.forwardingHistoryEvents.data.length > 0) {\n this.commonService.downloadFile(this.forwardingHistoryEvents.data, 'Forwarding-history');\n }\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxLayoutAlign=\"start stretch\" class=\"padding-gap\">\n <div *ngIf=\"errorMessage !== ''\" class=\"p-2 error-border my-2\">{{errorMessage}}</div>\n <div *ngIf=\"errorMessage === ''\" fxLayout=\"column\" fxLayout.gt-md=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" class=\"page-sub-title-container mt-2\">\n <div fxLayout=\"column\" fxFlex=\"49\" fxLayoutAlign=\"start stretch\" class=\"mb-4\">\n <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}\">\n <div fxFlex=\"70\">Incoming</div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <!-- <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" [(ngModel)]=\"selFilterByIn\" (selectionChange)=\"selFilterIn=''; applyFilterIncoming()\" name=\"filterByIn\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns)\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput [(ngModel)]=\"selFilterIn\" (input)=\"applyFilterIncoming()\" (keyup)=\"applyFilterIncoming()\" name=\"filterin\" placeholder=\"Filter\">\n </mat-form-field> -->\n </div>\n </div>\n <div fxLayout=\"column\" fxLayoutAlign=\"start start\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #tableIn mat-table matSort class=\"overflow-auto incoming-table\" [dataSource]=\"routingPeersIncoming\">\n <ng-container matColumnDef=\"channelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Channel ID</th>\n <td *matCellDef=\"let rPeer\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{rPeer?.channelId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"alias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Peer Alias</th>\n <td *matCellDef=\"let rPeer\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{rPeer?.alias}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"events\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Events</th>\n <td *matCellDef=\"let rPeer\" mat-cell><span fxLayoutAlign=\"end center\">{{rPeer.events | number}}</span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"totalAmount\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Amount (Sats)</th>\n <td *matCellDef=\"let rPeer\" mat-cell><span fxLayoutAlign=\"end center\">{{rPeer.totalAmount | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"totalFee\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Fee (Sats)</th>\n <td *matCellDef=\"let rPeer\" mat-cell><span fxLayoutAlign=\"end center\">{{rPeer.totalFee | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"no_incoming_event\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No incoming routing peer available.</p>\n <p *ngIf=\"(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting incoming routing peers...</p>\n <p *ngIf=\"(!routingPeersIncoming?.data || routingPeersIncoming?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_incoming_event']\" mat-footer-row [ngClass]=\"{'display-none': routingPeersIncoming?.data && routingPeersIncoming?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n </div>\n <mat-paginator #paginatorIn class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n </div>\n <div fxLayout=\"column\" fxFlex=\"49\" fxLayoutAlign=\"end stretch\" class=\"mb-4\">\n <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}\">\n <div fxFlex=\"70\">Outgoing</div>\n <div fxFlex.gt-xs=\"30\" fxLayoutAlign.gt-xs=\"space-between center\" fxLayout=\"row\" fxLayoutAlign=\"space-between stretch\">\n <!-- <mat-form-field fxFlex=\"49\">\n <mat-select placeholder=\"Filter By\" tabindex=\"1\" [(ngModel)]=\"selFilterByOut\" (selectionChange)=\"selFilterOut=''; applyFilterOutgoing()\" name=\"filterByOut\">\n <mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxFlex=\"49\">\n <input matInput [(ngModel)]=\"selFilterOut\" (input)=\"applyFilterOutgoing()\" (keyup)=\"applyFilterOutgoing()\" name=\"filterout\" placeholder=\"Filter\">\n </mat-form-field> -->\n </div>\n </div>\n <div fxLayout=\"column\" fxLayoutAlign=\"start end\" fxFlex=\"100\" class=\"table-container\" [perfectScrollbar]>\n <mat-progress-bar *ngIf=\"apiCallStatus.status === apiCallStatusEnum.INITIATED\" mode=\"indeterminate\"></mat-progress-bar>\n <table #tableOut mat-table matSort class=\"overflow-auto outgoing-table\" [dataSource]=\"routingPeersOutgoing\">\n <ng-container matColumnDef=\"channelId\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Channel ID</th>\n <td *matCellDef=\"let rPeer\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{rPeer?.channelId}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"alias\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header>Peer Alias</th>\n <td *matCellDef=\"let rPeer\" mat-cell>\n <div class=\"ellipsis-parent\" [ngStyle]=\"{'width': (screenSize === screenSizeEnum.XS) ? '10rem' : colWidth}\">\n <span class=\"ellipsis-child\">{{rPeer?.alias}}</span>\n </div>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"events\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Events</th>\n <td *matCellDef=\"let rPeer\" mat-cell><span fxLayoutAlign=\"end center\">{{rPeer.events | number}}</span>\n </td>\n </ng-container>\n <ng-container matColumnDef=\"totalAmount\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Amount (Sats)</th>\n <td *matCellDef=\"let rPeer\" mat-cell><span fxLayoutAlign=\"end center\">{{rPeer.totalAmount | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"totalFee\">\n <th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition=\"before\">Fee (Sats)</th>\n <td *matCellDef=\"let rPeer\" mat-cell><span fxLayoutAlign=\"end center\">{{rPeer.totalFee | number}}</span></td>\n </ng-container>\n <ng-container matColumnDef=\"no_outgoing_event\">\n <td *matFooterCellDef mat-footer-cellcolspan=\"4\">\n <p *ngIf=\"(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.COMPLETED\">No outgoing routing peer available.</p>\n <p *ngIf=\"(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.INITIATED\">Getting outgoing routing peers...</p>\n <p *ngIf=\"(!routingPeersOutgoing?.data || routingPeersOutgoing?.data?.length<1) && apiCallStatus.status === apiCallStatusEnum.ERROR\">{{errorMessage}}</p>\n </td>\n </ng-container>\n <tr *matFooterRowDef=\"['no_outgoing_event']\" mat-footer-row [ngClass]=\"{'display-none': routingPeersOutgoing?.data && routingPeersOutgoing?.data?.length>0}\"></tr>\n <tr *matHeaderRowDef=\"displayedColumns\" mat-header-row></tr>\n <tr *matRowDef=\"let row; columns: displayedColumns;\" mat-row></tr>\n </table>\n <mat-paginator #paginatorOut class=\"mb-1\" [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" [showFirstLastButtons]=\"screenSize === screenSizeEnum.XS ? false : true\"></mat-paginator>\n </div>\n </div>\n </div>\n</div>\n","import { Component, OnInit, AfterViewInit, ViewChild, OnDestroy } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\n\nimport { MatSort } from '@angular/material/sort';\nimport { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';\nimport { MatTableDataSource } from '@angular/material/table';\nimport { PaymentRelayed, Payments, RoutingPeers } from '../../../shared/models/eclModels';\nimport { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { CommonService } from '../../../shared/services/common.service';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { eclPageSettings, payments } from '../../store/ecl.selector';\nimport { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';\nimport { CamelCaseWithSpacesPipe } from '../../../shared/pipes/app.pipe';\n\n@Component({\n selector: 'rtl-ecl-routing-peers',\n templateUrl: './routing-peers.component.html',\n styleUrls: ['./routing-peers.component.scss'],\n providers: [\n { provide: MatPaginatorIntl, useValue: getPaginatorLabel('Peers') }\n ]\n})\nexport class ECLRoutingPeersComponent implements OnInit, AfterViewInit, OnDestroy {\n\n @ViewChild('tableIn', { read: MatSort, static: false }) sortIn: MatSort;\n @ViewChild('tableOut', { read: MatSort, static: false }) sortOut: MatSort;\n @ViewChild('paginatorIn', { static: false }) paginatorIn: MatPaginator | undefined;\n @ViewChild('paginatorOut', { static: false }) paginatorOut: MatPaginator | undefined;\n public nodePageDefs = ECL_PAGE_DEFS;\n public selFilterByIn = 'all';\n public selFilterByOut = 'all';\n public colWidth = '20rem';\n public PAGE_ID = 'routing';\n public tableSetting: TableSetting = { tableId: 'routing_peers', recordsPerPage: PAGE_SIZE, sortBy: 'totalFee', sortOrder: SortOrderEnum.DESCENDING };\n public routingPeersData: PaymentRelayed[] = [];\n public displayedColumns: any[] = [];\n public routingPeersIncoming: any = new MatTableDataSource([]);\n public routingPeersOutgoing: any = new MatTableDataSource([]);\n public pageSize = PAGE_SIZE;\n public pageSizeOptions = PAGE_SIZE_OPTIONS;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n public errorMessage = '';\n public filterIn = '';\n public filterOut = '';\n public apiCallStatus: ApiCallStatusPayload | null = null;\n public apiCallStatusEnum = APICallStatusEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {\n this.screenSize = this.commonService.getScreenSize();\n }\n\n ngOnInit() {\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = settings.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = this.apiCallStatus.message || '';\n }\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / (this.displayedColumns.length * 2)) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n this.store.select(payments).pipe(takeUntil(this.unSubs[1])).\n subscribe((paymentsSelector: { payments: Payments, apiCallStatus: ApiCallStatusPayload }) => {\n this.errorMessage = '';\n this.apiCallStatus = paymentsSelector.apiCallStatus;\n if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {\n this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;\n }\n this.routingPeersData = paymentsSelector.payments && paymentsSelector.payments.relayed ? paymentsSelector.payments.relayed : [];\n if (this.routingPeersData.length > 0 && this.sortIn && this.paginatorIn && this.sortOut && this.paginatorOut) {\n this.loadRoutingPeersTable(this.routingPeersData);\n }\n this.logger.info(paymentsSelector);\n });\n }\n\n ngAfterViewInit() {\n if (this.routingPeersData.length > 0 && this.sortIn && this.paginatorIn && this.sortOut && this.paginatorOut) {\n this.loadRoutingPeersTable(this.routingPeersData);\n }\n }\n\n applyFilterIncoming() {\n this.routingPeersIncoming.filter = this.filterIn.trim().toLowerCase();\n }\n\n applyFilterOutgoing() {\n this.routingPeersOutgoing.filter = this.filterOut.trim().toLowerCase();\n }\n\n getLabel(column: string) {\n const returnColumn: ColumnDefinition = this.nodePageDefs[this.PAGE_ID][this.tableSetting.tableId].allowedColumns.find((col) => col.column === column);\n return returnColumn ? returnColumn.label ? returnColumn.label : this.camelCaseWithSpaces.transform(returnColumn.column, '_') : this.commonService.titleCase(column);\n }\n\n setFilterPredicate() {\n this.routingPeersIncoming.filterPredicate = (rowDataIn: RoutingPeers, fltr: string) => {\n let rowToFilterIn = '';\n switch (this.selFilterByIn) {\n case 'all':\n rowToFilterIn = JSON.stringify(rowDataIn).toLowerCase();\n break;\n\n default:\n rowToFilterIn = typeof rowDataIn[this.selFilterByIn] === 'string' ? rowDataIn[this.selFilterByIn].toLowerCase() : typeof rowDataIn[this.selFilterByIn] === 'boolean' ? (rowDataIn[this.selFilterByIn] ? 'yes' : 'no') : rowDataIn[this.selFilterByIn].toString();\n break;\n }\n return rowToFilterIn.includes(fltr);\n };\n\n this.routingPeersOutgoing.filterPredicate = (rowDataOut: RoutingPeers, fltr: string) => {\n let rowToFilterOut = '';\n switch (this.selFilterByOut) {\n case 'all':\n rowToFilterOut = JSON.stringify(rowDataOut).toLowerCase();\n break;\n\n case 'total_amount':\n case 'total_fee':\n rowToFilterOut = ((+(rowDataOut[this.selFilterByOut] || 0)) / 1000)?.toString() || '';\n break;\n\n default:\n rowToFilterOut = typeof rowDataOut[this.selFilterByOut] === 'string' ? rowDataOut[this.selFilterByOut].toLowerCase() : typeof rowDataOut[this.selFilterByOut] === 'boolean' ? (rowDataOut[this.selFilterByOut] ? 'yes' : 'no') : rowDataOut[this.selFilterByOut].toString();\n break;\n }\n return rowToFilterOut.includes(fltr);\n };\n }\n\n loadRoutingPeersTable(forwardingEvents: PaymentRelayed[]) {\n if (forwardingEvents.length > 0) {\n const results = this.groupRoutingPeers(forwardingEvents);\n this.routingPeersIncoming = new MatTableDataSource<RoutingPeers>(results[0]);\n this.routingPeersIncoming.sort = this.sortIn;\n this.routingPeersIncoming.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.routingPeersIncoming.paginator = this.paginatorIn;\n this.logger.info(this.routingPeersIncoming);\n this.routingPeersOutgoing = new MatTableDataSource<RoutingPeers>(results[1]);\n this.routingPeersOutgoing.sort = this.sortOut;\n this.routingPeersOutgoing.sort?.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });\n this.routingPeersOutgoing.paginator = this.paginatorOut;\n this.logger.info(this.routingPeersOutgoing);\n } else {\n // To reset table after other Forwarding history calls\n this.routingPeersIncoming = new MatTableDataSource<RoutingPeers>([]);\n this.routingPeersOutgoing = new MatTableDataSource<RoutingPeers>([]);\n }\n this.setFilterPredicate();\n this.applyFilterIncoming();\n this.applyFilterOutgoing();\n }\n\n groupRoutingPeers(forwardingEvents: PaymentRelayed[]) {\n const incomingResults: RoutingPeers[] = [];\n const outgoingResults: RoutingPeers[] = [];\n forwardingEvents.forEach((event: PaymentRelayed) => {\n const incoming: any = incomingResults.find((result) => result.channelId === event.fromChannelId);\n const outgoing: any = outgoingResults.find((result) => result.channelId === event.toChannelId);\n if (!incoming) {\n incomingResults.push({ channelId: event.fromChannelId, alias: event.fromChannelAlias, events: 1, totalAmount: +event.amountIn, totalFee: (event.amountIn - event.amountOut) });\n } else {\n incoming.events++;\n incoming.totalAmount = +incoming.totalAmount + +event.amountIn;\n incoming.totalFee = +incoming.totalFee + (event.amountIn - event.amountOut);\n }\n if (!outgoing) {\n outgoingResults.push({ channelId: event.toChannelId, alias: event.toChannelAlias, events: 1, totalAmount: +event.amountOut, totalFee: (event.amountIn - event.amountOut) });\n } else {\n outgoing.events++;\n outgoing.totalAmount = +outgoing.totalAmount + +event.amountOut;\n outgoing.totalFee = +outgoing.totalFee + (event.amountIn - event.amountOut);\n }\n });\n return [this.commonService.sortDescByKey(incomingResults, 'totalFee'), this.commonService.sortDescByKey(outgoingResults, 'totalFee')];\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"row\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faChartBar\"></fa-icon>\n <span class=\"page-title\">Reports</span>\n</div>\n<div fxLayout=\"column\" class=\"padding-gap-x\">\n <mat-card>\n <mat-card-content fxLayout=\"column\">\n <nav mat-tab-nav-bar [tabPanel]=\"tabPanel\">\n <div *ngFor=\"let link of links\" mat-tab-link class=\"mat-tab-label\" [active]=\"activeLink === link.link\" routerLink=\"{{link.link}}\" (click)=\"activeLink = link.link\">{{link.name}}</div>\n </nav>\n <mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>\n <!-- <nav mat-tab-nav-bar>\n <div role=\"tab\" mat-tab-link *ngFor=\"let link of links\" class=\"mat-tab-label\" [active]=\"activeLink === link.link\" (click)=\"activeLink = link.link\" routerLink=\"{{link.link}}\">{{link.name}}</div>\n </nav> -->\n <router-outlet></router-outlet> \n </mat-card-content>\n </mat-card>\n</div>\n ","import { Component, OnDestroy, OnInit } from '@angular/core';\nimport { Router, ResolveEnd, Event } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { faChartBar } from '@fortawesome/free-solid-svg-icons';\n\n@Component({\n selector: 'rtl-ecl-reports',\n templateUrl: './reports.component.html',\n styleUrls: ['./reports.component.scss']\n})\nexport class ECLReportsComponent implements OnInit, OnDestroy {\n\n public faChartBar = faChartBar;\n public links = [{ link: 'routingreport', name: 'Routing' }, { link: 'transactions', name: 'Transactions' }];\n public activeLink = this.links[0].link;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private router: Router) { }\n\n ngOnInit() {\n const linkFound = this.links.find((link) => this.router.url.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n this.router.events.pipe(takeUntil(this.unSubs[0]), filter((e) => e instanceof ResolveEnd)).\n subscribe({\n next: (value: ResolveEnd | Event) => {\n const linkFound = this.links.find((link) => (<ResolveEnd>value).urlAfterRedirects.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n }\n });\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxLayoutAlign=\"start stretch\" fxFlex=\"100\" class=\"padding-gap-x-large\">\n <rtl-horizontal-scroller (stepChanged)=\"onSelectionChange($event)\"></rtl-horizontal-scroller>\n <div fxLayout=\"column\" fxLayoutAlign=\"center center\" class=\"padding-gap-x\">\n <mat-radio-group class=\"my-1\" color=\"primary\" name=\"selReportBy\" fxFlex=\"100\" fxLayoutAlign=\"start start\" [(ngModel)]=\"selReportBy\" (change)=\"onSelReportByChange()\">\n <span class=\"mr-2\">Report By: </span>\n <mat-radio-button class=\"mr-2\" tabindex=\"1\" value=\"{{reportBy.FEES}}\">Fees</mat-radio-button>\n <mat-radio-button tabindex=\"2\" value=\"{{reportBy.EVENTS}}\">Events</mat-radio-button>\n </mat-radio-group>\n </div>\n <div fxLayout=\"column\" fxLayoutAlign=\"start stretch\" fxFlex=\"100\" class=\"padding-gap-x\">\n <div *ngIf=\"routingReportData.length > 0 && filteredEventsBySelectedPeriod.length > 0\" fxLayout=\"column\" fxLayoutAlign=\"center center\" fxFlex=\"100\" class=\"font-size-120 font-bold-700 mt-1\"\n [@fadeIn]=\"totalFeeSat\">{{(totalFeeSat || 0) | number:'1.0-2'}} Sats/{{(filteredEventsBySelectedPeriod.length || 0) | number}} Events</div>\n <div *ngIf=\"routingReportData.length <= 0 || filteredEventsBySelectedPeriod.length <= 0\" fxLayout=\"column\" fxLayoutAlign=\"center center\" fxFlex=\"100\" class=\"font-size-120 mt-1\">No routing report for the selected period</div>\n <div class=\"mt-1\">\n <ngx-charts-bar-vertical\n *ngIf=\"routingReportData.length > 0 && filteredEventsBySelectedPeriod.length > 0\"\n class=\"one-color\"\n [view]=\"view\"\n [results]=\"routingReportData\"\n [gradient]=\"false\"\n [xAxis]=\"true\"\n [yAxis]=\"true\"\n [showXAxisLabel]=\"true\"\n [showYAxisLabel]=\"showYAxisLabel\"\n [xAxisLabel]=\"xAxisLabel\"\n [yAxisLabel]=\"yAxisLabel\"\n [showGridLines]=\"false\"\n [showDataLabel]=\"false\"\n (select)=\"onChartBarSelected($event)\"\n (mouseup)=\"onChartMouseUp($event)\">\n <ng-template #tooltipTemplate let-model=\"model\">\n <span>\n <span class=\"tooltip-label\">Events: {{((selReportBy === reportBy.EVENTS ? model.value : model.extra.totalEvents) || 0) | number}}</span>\n <span class=\"tooltip-label\">Fee: {{((selReportBy === reportBy.EVENTS ? model.extra.totalFees : model.value) || 0) | number:'1.0-2'}}</span>\n </span>\n </ng-template>\n </ngx-charts-bar-vertical>\n </div>\n <div class=\"mt-1\">\n <rtl-ecl-forwarding-history *ngIf=\"filteredEventsBySelectedPeriod.length > 0\" [pageId]=\"'reports'\" [tableId]=\"'routing'\"[eventsData]=\"filteredEventsBySelectedPeriod\" [selFilter]=\"eventFilterValue\"></rtl-ecl-forwarding-history>\n </div>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\n\nimport { PaymentRelayed, Payments } from '../../../shared/models/eclModels';\nimport { CommonService } from '../../../shared/services/common.service';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { MONTHS, ReportBy, ScreenSizeEnum, SCROLL_RANGES } from '../../../shared/services/consts-enums-functions';\nimport { fadeIn } from '../../../shared/animation/opacity-animation';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { payments } from '../../store/ecl.selector';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\n\n@Component({\n selector: 'rtl-ecl-routing-report',\n templateUrl: './routing-report.component.html',\n styleUrls: ['./routing-report.component.scss'],\n animations: [fadeIn]\n})\nexport class ECLRoutingReportComponent implements OnInit, OnDestroy {\n\n public reportPeriod = SCROLL_RANGES[0];\n public secondsInADay = 24 * 60 * 60;\n public events: PaymentRelayed[] = [];\n public filteredEventsBySelectedPeriod: PaymentRelayed[] = [];\n public eventFilterValue = '';\n public reportBy = ReportBy;\n public selReportBy = ReportBy.FEES;\n public totalFeeSat: number | null = null;\n public today = new Date(Date.now());\n public startDate = new Date(this.today.getFullYear(), this.today.getMonth(), 1, 0, 0, 0);\n public endDate = new Date(this.today.getFullYear(), this.today.getMonth(), this.getMonthDays(this.today.getMonth(), this.today.getFullYear()), 23, 59, 59);\n public routingReportData: any = [];\n public view: [number, number] = [350, 350];\n public screenPaddingX = 100;\n public gradient = true;\n public xAxisLabel = 'Date';\n public yAxisLabel = 'Fee (Sats)';\n public showYAxisLabel = true;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>) { }\n\n ngOnInit() {\n this.screenSize = this.commonService.getScreenSize();\n this.showYAxisLabel = !(this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM);\n this.store.select(payments).pipe(takeUntil(this.unSubs[0])).\n subscribe((paymentsSelector: { payments: Payments, apiCallStatus: ApiCallStatusPayload }) => {\n this.events = paymentsSelector.payments && paymentsSelector.payments.relayed ? paymentsSelector.payments.relayed : [];\n this.filterForwardingEvents(this.startDate, this.endDate);\n this.logger.info(paymentsSelector);\n });\n this.commonService.containerSizeUpdated.pipe(takeUntil(this.unSubs[1])).subscribe((CONTAINER_SIZE) => {\n switch (this.screenSize) {\n case ScreenSizeEnum.MD:\n this.screenPaddingX = CONTAINER_SIZE.width / 10;\n break;\n\n case ScreenSizeEnum.LG:\n this.screenPaddingX = CONTAINER_SIZE.width / 16;\n break;\n\n default:\n this.screenPaddingX = CONTAINER_SIZE.width / 20;\n break;\n }\n this.view = [CONTAINER_SIZE.width - this.screenPaddingX, CONTAINER_SIZE.height / 2.2];\n this.logger.info('Container Size: ' + JSON.stringify(CONTAINER_SIZE));\n this.logger.info('View: ' + JSON.stringify(this.view));\n });\n }\n\n filterForwardingEvents(start: Date, end: Date) {\n const startDateInSeconds = Math.round(start.getTime() / 1000);\n const endDateInSeconds = Math.round(end.getTime() / 1000);\n this.logger.info('Filtering Forwarding Events Starting at ' + new Date(Date.now()).toLocaleString() + ' From ' + start.toLocaleString() + ' To ' + end.toLocaleString());\n this.filteredEventsBySelectedPeriod = [];\n this.routingReportData = [];\n this.totalFeeSat = null;\n if (this.events && this.events.length > 0) {\n this.events.forEach((event) => {\n if (Math.floor((event.timestamp || 0) / 1000) >= startDateInSeconds && Math.floor((event.timestamp || 0) / 1000) < endDateInSeconds) {\n this.filteredEventsBySelectedPeriod.push(event);\n }\n });\n this.routingReportData = this.selReportBy === this.reportBy.EVENTS ? this.prepareEventsReport(start) : this.prepareFeeReport(start);\n }\n this.logger.info('Filtering Forwarding Events Finished at ' + new Date(Date.now()).toLocaleString());\n }\n\n @HostListener('mouseup', ['$event']) onChartMouseUp(e) {\n if (e.srcElement.tagName === 'svg' && e.srcElement.classList.length > 0 && e.srcElement.classList[0] === 'ngx-charts') {\n this.eventFilterValue = '';\n }\n }\n\n onChartBarSelected(event) {\n if (this.reportPeriod === SCROLL_RANGES[1]) {\n this.eventFilterValue = event.name + '/' + this.startDate.getFullYear();\n } else {\n this.eventFilterValue = event.name.toString().padStart(2, '0') + '/' + MONTHS[this.startDate.getMonth()].name + '/' + this.startDate.getFullYear();\n }\n }\n\n prepareFeeReport(start: Date) {\n const startDateInSeconds = Math.round(start.getTime() / 1000);\n const feeReport: any = [];\n this.totalFeeSat = 0;\n this.logger.info('Fee Report Prepare Starting at ' + new Date(Date.now()).toLocaleString() + ' From ' + start.toLocaleString());\n if (this.reportPeriod === SCROLL_RANGES[1]) {\n for (let i = 0; i < 12; i++) {\n feeReport.push({ name: MONTHS[i].name, value: 0.0, extra: { totalEvents: 0 } });\n }\n this.filteredEventsBySelectedPeriod?.map((event) => {\n const monthNumber = new Date((event.timestamp || 0)).getMonth();\n feeReport[monthNumber].value = feeReport[monthNumber].value + ((event.amountIn || 0) - (event.amountOut || 0));\n feeReport[monthNumber].extra.totalEvents = feeReport[monthNumber].extra.totalEvents + 1;\n this.totalFeeSat = (this.totalFeeSat ? this.totalFeeSat : 0) + ((event.amountIn || 0) - (event.amountOut || 0));\n return this.filteredEventsBySelectedPeriod;\n });\n } else {\n for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {\n feeReport.push({ name: i + 1, value: 0.0, extra: { totalEvents: 0 } });\n }\n this.filteredEventsBySelectedPeriod?.map((event) => {\n const dateNumber = Math.floor((Math.floor((event.timestamp || 0) / 1000) - startDateInSeconds) / this.secondsInADay);\n feeReport[dateNumber].value = feeReport[dateNumber].value + ((event.amountIn || 0) - (event.amountOut || 0));\n feeReport[dateNumber].extra.totalEvents = feeReport[dateNumber].extra.totalEvents + 1;\n this.totalFeeSat = (this.totalFeeSat ? this.totalFeeSat : 0) + ((event.amountIn || 0) - (event.amountOut || 0));\n return this.filteredEventsBySelectedPeriod;\n });\n }\n this.logger.info('Fee Report Prepare Finished at ' + new Date(Date.now()).toLocaleString());\n return feeReport;\n }\n\n prepareEventsReport(start: Date) {\n const startDateInSeconds = Math.round(start.getTime() / 1000);\n const eventsReport: any = [];\n this.totalFeeSat = 0;\n this.logger.info('Events Report Prepare Starting at ' + new Date(Date.now()).toLocaleString() + ' From ' + start.toLocaleString());\n if (this.reportPeriod === SCROLL_RANGES[1]) {\n for (let i = 0; i < 12; i++) {\n eventsReport.push({ name: MONTHS[i].name, value: 0, extra: { totalFees: 0.0 } });\n }\n this.filteredEventsBySelectedPeriod?.map((event) => {\n const monthNumber = new Date((event.timestamp || 0)).getMonth();\n eventsReport[monthNumber].value = eventsReport[monthNumber].value + 1;\n eventsReport[monthNumber].extra.totalFees = eventsReport[monthNumber].extra.totalFees + ((event.amountIn || 0) - (event.amountOut || 0));\n this.totalFeeSat = (this.totalFeeSat ? this.totalFeeSat : 0) + ((event.amountIn || 0) - (event.amountOut || 0));\n return this.filteredEventsBySelectedPeriod;\n });\n } else {\n for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {\n eventsReport.push({ name: i + 1, value: 0, extra: { totalFees: 0.0 } });\n }\n this.filteredEventsBySelectedPeriod?.map((event) => {\n const dateNumber = Math.floor((Math.floor((event.timestamp || 0) / 1000) - startDateInSeconds) / this.secondsInADay);\n eventsReport[dateNumber].value = eventsReport[dateNumber].value + 1;\n eventsReport[dateNumber].extra.totalFees = eventsReport[dateNumber].extra.totalFees + ((event.amountIn || 0) - (event.amountOut || 0));\n this.totalFeeSat = (this.totalFeeSat ? this.totalFeeSat : 0) + ((event.amountIn || 0) - (event.amountOut || 0));\n return this.filteredEventsBySelectedPeriod;\n });\n }\n this.logger.info('Events Report Prepare Finished at ' + new Date(Date.now()).toLocaleString());\n return eventsReport;\n }\n\n onSelectionChange(selectedValues: { selDate: Date, selScrollRange: string }) {\n const selMonth = selectedValues.selDate.getMonth();\n const selYear = selectedValues.selDate.getFullYear();\n this.reportPeriod = selectedValues.selScrollRange;\n if (this.reportPeriod === SCROLL_RANGES[1]) {\n this.startDate = new Date(selYear, 0, 1, 0, 0, 0);\n this.endDate = new Date(selYear, 11, 31, 23, 59, 59);\n } else {\n this.startDate = new Date(selYear, selMonth, 1, 0, 0, 0);\n this.endDate = new Date(selYear, selMonth, this.getMonthDays(selMonth, selYear), 23, 59, 59);\n }\n this.filterForwardingEvents(this.startDate, this.endDate);\n this.eventFilterValue = '';\n }\n\n getMonthDays(selMonth: number, selYear: number) {\n return (selMonth === 1 && selYear % 4 === 0) ? (MONTHS[selMonth].days + 1) : MONTHS[selMonth].days;\n }\n\n onSelReportByChange() {\n this.yAxisLabel = this.selReportBy === this.reportBy.EVENTS ? 'Events' : 'Fee (Sats)';\n this.routingReportData = this.selReportBy === this.reportBy.EVENTS ? this.prepareEventsReport(this.startDate) : this.prepareFeeReport(this.startDate);\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","<div fxLayout=\"column\" fxLayoutAlign=\"start stretch\" fxFlex=\"100\" class=\"padding-gap-x-large\">\n <rtl-horizontal-scroller (stepChanged)=\"onSelectionChange($event)\"></rtl-horizontal-scroller>\n <div fxLayout=\"column\" fxLayoutAlign=\"start stretch\" fxFlex=\"100\" class=\"padding-gap-x\">\n <div *ngIf=\"transactionsNonZeroReportData.length > 0\" fxLayout=\"column\" fxLayoutAlign=\"center center\" fxFlex=\"100\" class=\"font-size-120 font-bold-700 mt-1\" [@fadeIn]=\"transactionsReportSummary\">\n <div *ngIf=\"transactionsReportSummary.paymentsSelectedPeriod\" fxLayout=\"row\" fxLayoutAlign=\"start stretch\" fxFlex=\"100\">\n Paid {{(transactionsReportSummary.amountPaidSelectedPeriod || 0) | number:'1.0-2'}} Sats/{{transactionsReportSummary.paymentsSelectedPeriod | number}} Payments\n </div>\n <div *ngIf=\"transactionsReportSummary.invoicesSelectedPeriod\" fxLayout=\"row\" fxLayoutAlign=\"start stretch\" fxFlex=\"100\">\n Received {{(transactionsReportSummary.amountReceivedSelectedPeriod || 0) | number:'1.0-2'}} Sats/{{transactionsReportSummary.invoicesSelectedPeriod | number}} Invoices\n </div>\n </div>\n <div *ngIf=\"transactionsNonZeroReportData.length <= 0\" fxLayout=\"column\" fxLayoutAlign=\"center center\" fxFlex=\"100\" class=\"font-size-120 mt-1\">No transactions report for the selected period</div>\n <div class=\"mt-1\">\n <ngx-charts-bar-vertical-2d\n *ngIf=\"transactionsNonZeroReportData.length > 0\"\n class=\"two-color\"\n [view]=\"view\"\n [results]=\"transactionsReportData\"\n [noBarWhenZero]=\"false\"\n [gradient]=\"false\"\n [xAxis]=\"true\"\n [yAxis]=\"true\"\n [showXAxisLabel]=\"true\"\n [showYAxisLabel]=\"showYAxisLabel\"\n [xAxisLabel]=\"xAxisLabel\"\n [yAxisLabel]=\"yAxisLabel\"\n [showGridLines]=\"false\"\n [showDataLabel]=\"false\"\n [groupPadding]=\"(reportPeriod === scrollRanges[0]) ? 2 : 8\"\n (select)=\"onChartBarSelected($event)\"\n (mouseup)=\"onChartMouseUp($event)\">\n <ng-template #tooltipTemplate let-model=\"model\">\n <span class=\"tooltip-label\">{{model.name}}: {{(model.value || 0) | number:'1.0-2'}}/# {{model.name === 'Paid' ? 'Payments' : 'Invoices'}}: {{(model.extra?.total || 0) | number}}</span>\n </ng-template>\n </ngx-charts-bar-vertical-2d> \n </div>\n <div class=\"mt-1\">\n <rtl-transactions-report-table *ngIf=\"transactionsNonZeroReportData.length > 0\" [displayedColumns]=\"displayedColumns\" [tableSetting]=\"tableSetting\" [dataList]=\"transactionsNonZeroReportData\" [dataRange]=\"reportPeriod\" [selFilter]=\"transactionFilterValue\"></rtl-transactions-report-table>\n </div>\n </div>\n</div>\n","import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil, withLatestFrom } from 'rxjs/operators';\nimport { Store } from '@ngrx/store';\n\nimport { PaymentSent, Invoice, Payments } from '../../../shared/models/eclModels';\nimport { CommonService } from '../../../shared/services/common.service';\nimport { APICallStatusEnum, ECL_DEFAULT_PAGE_SETTINGS, MONTHS, PAGE_SIZE, ScreenSizeEnum, SCROLL_RANGES, SortOrderEnum } from '../../../shared/services/consts-enums-functions';\nimport { fadeIn } from '../../../shared/animation/opacity-animation';\n\nimport { RTLState } from '../../../store/rtl.state';\nimport { eclPageSettings, invoices, payments } from '../../store/ecl.selector';\nimport { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';\nimport { LoggerService } from '../../../shared/services/logger.service';\nimport { PageSettings, TableSetting } from '../../../shared/models/pageSettings';\n\n@Component({\n selector: 'rtl-ecl-transactions-report',\n templateUrl: './transactions-report.component.html',\n styleUrls: ['./transactions-report.component.scss'],\n animations: [fadeIn]\n})\nexport class ECLTransactionsReportComponent implements OnInit, OnDestroy {\n\n public scrollRanges = SCROLL_RANGES;\n public reportPeriod = SCROLL_RANGES[0];\n public secondsInADay = 24 * 60 * 60;\n public payments: PaymentSent[] = [];\n public invoices: Invoice[] = [];\n public colWidth = '20rem';\n public PAGE_ID = 'reports';\n public tableSetting: TableSetting = { tableId: 'transactions', recordsPerPage: PAGE_SIZE, sortBy: 'date', sortOrder: SortOrderEnum.DESCENDING };\n public displayedColumns: any[] = ['date', 'amount_paid', 'num_payments', 'amount_received', 'num_invoices'];\n public transactionsReportSummary = { paymentsSelectedPeriod: 0, invoicesSelectedPeriod: 0, amountPaidSelectedPeriod: 0, amountReceivedSelectedPeriod: 0 };\n public transactionFilterValue = '';\n public today = new Date(Date.now());\n public startDate = new Date(this.today.getFullYear(), this.today.getMonth(), 1, 0, 0, 0);\n public endDate = new Date(this.today.getFullYear(), this.today.getMonth(), this.getMonthDays(this.today.getMonth(), this.today.getFullYear()), 23, 59, 59);\n public transactionsReportData: any = [];\n public transactionsNonZeroReportData: any = [];\n public view: [number, number] = [350, 350];\n public screenPaddingX = 100;\n public gradient = true;\n public xAxisLabel = 'Date';\n public yAxisLabel = 'Amount (Sats)';\n public showYAxisLabel = true;\n public screenSize = '';\n public screenSizeEnum = ScreenSizeEnum;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>) { }\n\n ngOnInit() {\n this.screenSize = this.commonService.getScreenSize();\n this.showYAxisLabel = !(this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM);\n this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[0])).\n subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {\n this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;\n if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));\n } else {\n this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));\n }\n this.displayedColumns.push('actions');\n this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 10) + 'rem' : '20rem';\n this.logger.info(this.displayedColumns);\n });\n\n this.store.select(payments).pipe(takeUntil(this.unSubs[1]),\n withLatestFrom(this.store.select(invoices))).\n subscribe(([paymentsSelector, invoicesSelector]: [({ payments: Payments, apiCallStatus: ApiCallStatusPayload }), ({ invoices: Invoice[], apiCallStatus: ApiCallStatusPayload })]) => {\n this.payments = paymentsSelector.payments.sent ? paymentsSelector.payments.sent : [];\n this.invoices = invoicesSelector.invoices ? invoicesSelector.invoices : [];\n if (this.payments.length > 0 || this.invoices.length > 0) {\n this.transactionsReportData = this.filterTransactionsForSelectedPeriod(this.startDate, this.endDate);\n this.transactionsNonZeroReportData = this.prepareTableData();\n }\n });\n this.commonService.containerSizeUpdated.pipe(takeUntil(this.unSubs[2])).subscribe((CONTAINER_SIZE) => {\n switch (this.screenSize) {\n case ScreenSizeEnum.MD:\n this.screenPaddingX = CONTAINER_SIZE.width / 10;\n break;\n\n case ScreenSizeEnum.LG:\n this.screenPaddingX = CONTAINER_SIZE.width / 16;\n break;\n\n default:\n this.screenPaddingX = CONTAINER_SIZE.width / 20;\n break;\n }\n this.view = [CONTAINER_SIZE.width - this.screenPaddingX, CONTAINER_SIZE.height / 2.2];\n this.logger.info('Container Size: ' + JSON.stringify(CONTAINER_SIZE));\n this.logger.info('View: ' + JSON.stringify(this.view));\n });\n }\n\n @HostListener('mouseup', ['$event']) onChartMouseUp(e) {\n if (e.srcElement.tagName === 'svg' && e.srcElement.classList.length > 0 && e.srcElement.classList[0] === 'ngx-charts') {\n this.transactionFilterValue = '';\n }\n }\n\n onChartBarSelected(event) {\n if (this.reportPeriod === SCROLL_RANGES[1]) {\n this.transactionFilterValue = event.series.toString() + '/' + this.startDate.getFullYear();\n } else {\n this.transactionFilterValue = event.series.toString().padStart(2, '0') + '/' + MONTHS[this.startDate.getMonth()].name + '/' + this.startDate.getFullYear();\n }\n }\n\n filterTransactionsForSelectedPeriod(start: Date, end: Date) {\n const startDateInSeconds = Math.round(start.getTime() / 1000);\n const endDateInSeconds = Math.round(end.getTime() / 1000);\n const transactionsReport: any = [];\n this.transactionsReportSummary = { paymentsSelectedPeriod: 0, invoicesSelectedPeriod: 0, amountPaidSelectedPeriod: 0, amountReceivedSelectedPeriod: 0 };\n const filteredPayments = this.payments?.filter((payment) => payment.firstPartTimestamp && Math.floor(payment.firstPartTimestamp / 1000) >= startDateInSeconds && Math.floor(payment.firstPartTimestamp / 1000) < endDateInSeconds);\n const filteredInvoices = this.invoices?.filter((invoice) => invoice.status === 'received' && invoice.timestamp && invoice.timestamp >= startDateInSeconds && invoice.timestamp < endDateInSeconds);\n this.transactionsReportSummary.paymentsSelectedPeriod = filteredPayments.length;\n this.transactionsReportSummary.invoicesSelectedPeriod = filteredInvoices.length;\n if (this.reportPeriod === SCROLL_RANGES[1]) {\n for (let i = 0; i < 12; i++) {\n transactionsReport.push({ name: MONTHS[i].name, date: new Date(start.getFullYear(), i, 1, 0, 0, 0, 0), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] });\n }\n filteredPayments?.map((payment) => {\n const monthNumber = new Date(payment.firstPartTimestamp || 0).getMonth();\n this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + (payment.recipientAmount || 0);\n transactionsReport[monthNumber].series[0].value = transactionsReport[monthNumber].series[0].value + payment.recipientAmount;\n transactionsReport[monthNumber].series[0].extra.total = transactionsReport[monthNumber].series[0].extra.total + 1;\n return this.transactionsReportSummary;\n });\n filteredInvoices?.map((invoice) => {\n const monthNumber = new Date((invoice.timestamp || 0) * 1000).getMonth();\n this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + (invoice.amountSettled || 0);\n transactionsReport[monthNumber].series[1].value = transactionsReport[monthNumber].series[1].value + invoice.amountSettled;\n transactionsReport[monthNumber].series[1].extra.total = transactionsReport[monthNumber].series[1].extra.total + 1;\n return this.transactionsReportSummary;\n });\n } else {\n for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {\n transactionsReport.push({ name: (i + 1).toString(), date: new Date((((i) * this.secondsInADay) + startDateInSeconds) * 1000), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] });\n }\n filteredPayments?.map((payment) => {\n const dateNumber = Math.floor((Math.floor((payment.firstPartTimestamp || 0) / 1000) - startDateInSeconds) / this.secondsInADay);\n this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + (payment.recipientAmount || 0);\n transactionsReport[dateNumber].series[0].value = transactionsReport[dateNumber].series[0].value + payment.recipientAmount;\n transactionsReport[dateNumber].series[0].extra.total = transactionsReport[dateNumber].series[0].extra.total + 1;\n return this.transactionsReportSummary;\n });\n filteredInvoices?.map((invoice) => {\n const dateNumber = Math.floor(((invoice.timestamp || 0) - startDateInSeconds) / this.secondsInADay);\n this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + (invoice.amountSettled || 0);\n transactionsReport[dateNumber].series[1].value = transactionsReport[dateNumber].series[1].value + invoice.amountSettled;\n transactionsReport[dateNumber].series[1].extra.total = transactionsReport[dateNumber].series[1].extra.total + 1;\n return this.transactionsReportSummary;\n });\n }\n return transactionsReport;\n }\n\n prepareTableData() {\n return this.transactionsReportData?.reduce((acc, curr) => {\n if (curr.series[0].extra.total > 0 || curr.series[1].extra.total > 0) {\n return acc.concat({ date: curr.date, amount_paid: curr.series[0].value, num_payments: curr.series[0].extra.total, amount_received: curr.series[1].value, num_invoices: curr.series[1].extra.total });\n }\n return acc;\n }, []);\n }\n\n onSelectionChange(selectedValues: { selDate: Date, selScrollRange: string }) {\n const selMonth = selectedValues.selDate.getMonth();\n const selYear = selectedValues.selDate.getFullYear();\n this.reportPeriod = selectedValues.selScrollRange;\n if (this.reportPeriod === SCROLL_RANGES[1]) {\n this.startDate = new Date(selYear, 0, 1, 0, 0, 0);\n this.endDate = new Date(selYear, 11, 31, 23, 59, 59);\n } else {\n this.startDate = new Date(selYear, selMonth, 1, 0, 0, 0);\n this.endDate = new Date(selYear, selMonth, this.getMonthDays(selMonth, selYear), 23, 59, 59);\n }\n this.transactionsReportData = this.filterTransactionsForSelectedPeriod(this.startDate, this.endDate);\n this.transactionsNonZeroReportData = this.prepareTableData();\n this.transactionFilterValue = '';\n }\n\n getMonthDays(selMonth: number, selYear: number) {\n return (selMonth === 1 && selYear % 4 === 0) ? (MONTHS[selMonth].days + 1) : MONTHS[selMonth].days;\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n\n","<div fxLayout=\"row wrap\" fxLayoutAlign=\"start center\" class=\"page-title-container\">\n <fa-icon class=\"page-title-img mr-1\" [icon]=\"faSearch\"></fa-icon>\n <span class=\"page-title\">Graph Lookups</span>\n</div>\n<div fxLayout=\"column\" class=\"padding-gap-x\">\n <mat-card>\n <mat-card-content fxLayout=\"column\">\n <nav mat-tab-nav-bar [tabPanel]=\"tabPanel\">\n <div *ngFor=\"let link of links\" mat-tab-link class=\"mat-tab-label\" [active]=\"activeLink === link.link\" routerLink=\"{{link.link}}\" (click)=\"activeLink = link.link\">{{link.name}}</div>\n </nav>\n <mat-tab-nav-panel #tabPanel></mat-tab-nav-panel>\n <!-- <nav mat-tab-nav-bar>\n <div role=\"tab\" mat-tab-link *ngFor=\"let link of links\" class=\"mat-tab-label\" [active]=\"activeLink === link.link\" (click)=\"activeLink = link.link\" routerLink=\"{{link.link}}\">{{link.name}}</div>\n </nav> -->\n <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" class=\"mat-tab-body-wrapper\">\n <router-outlet></router-outlet>\n </div>\n </mat-card-content>\n </mat-card>\n</div>\n ","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Router, ResolveEnd, Event } from '@angular/router';\nimport { Subject } from 'rxjs';\nimport { takeUntil, filter } from 'rxjs/operators';\nimport { faSearch } from '@fortawesome/free-solid-svg-icons';\n\n@Component({\n selector: 'rtl-ecl-graph',\n templateUrl: './graph.component.html',\n styleUrls: ['./graph.component.scss']\n})\nexport class ECLGraphComponent implements OnInit, OnDestroy {\n\n faSearch = faSearch;\n public links = [{ link: 'lookups', name: 'Lookup' }, { link: 'queryroutes', name: 'Query Routes' }];\n public activeLink = this.links[0].link;\n private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];\n\n constructor(private router: Router) { }\n\n ngOnInit() {\n const linkFound = this.links.find((link) => this.router.url.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n this.router.events.pipe(takeUntil(this.unSubs[0]), filter((e) => e instanceof ResolveEnd)).\n subscribe({\n next: (value: ResolveEnd | Event) => {\n const linkFound = this.links.find((link) => (<ResolveEnd>value).urlAfterRedirects.includes(link.link));\n this.activeLink = linkFound ? linkFound.link : this.links[0].link;\n }\n });\n }\n\n ngOnDestroy() {\n this.unSubs.forEach((completeSub) => {\n completeSub.next(<any>null);\n completeSub.complete();\n });\n }\n\n}\n","import { Routes, RouterModule } from '@angular/router';\nimport { ModuleWithProviders } from '@angular/core';\n\nimport { ECLRootComponent } from './ecl-root.component';\nimport { ECLHomeComponent } from './home/home.component';\nimport { ECLOnChainComponent } from './on-chain/on-chain.component';\nimport { ECLConnectionsComponent } from './peers-channels/connections.component';\nimport { ECLTransactionsComponent } from './transactions/transactions.component';\nimport { ECLRoutingComponent } from './routing/routing.component';\nimport { ECLLookupsComponent } from './graph/lookups/lookups.component';\nimport { ECLOnChainReceiveComponent } from './on-chain/on-chain-receive/on-chain-receive.component';\nimport { ECLOnChainSendComponent } from './on-chain/on-chain-send/on-chain-send.component';\nimport { ECLChannelsTablesComponent } from './peers-channels/channels/channels-tables/channels-tables.component';\nimport { ECLChannelOpenTableComponent } from './peers-channels/channels/channels-tables/channel-open-table/channel-open-table.component';\nimport { ECLChannelPendingTableComponent } from './peers-channels/channels/channels-tables/channel-pending-table/channel-pending-table.component';\nimport { ECLPeersComponent } from './peers-channels/peers/peers.component';\nimport { ECLLightningPaymentsComponent } from './transactions/payments/lightning-payments.component';\nimport { ECLLightningInvoicesComponent } from './transactions/invoices/lightning-invoices.component';\nimport { ECLQueryRoutesComponent } from './graph/query-routes/query-routes.component';\nimport { ECLChannelInactiveTableComponent } from './peers-channels/channels/channels-tables/channel-inactive-table/channel-inactive-table.component';\nimport { ECLForwardingHistoryComponent } from './routing/forwarding-history/forwarding-history.component';\nimport { ECLRoutingPeersComponent } from './routing/routing-peers/routing-peers.component';\nimport { ECLReportsComponent } from './reports/reports.component';\nimport { ECLRoutingReportComponent } from './reports/routing/routing-report.component';\nimport { ECLTransactionsReportComponent } from './reports/transactions/transactions-report.component';\nimport { ECLUnlockedGuard } from '../shared/services/auth.guard';\nimport { NotFoundComponent } from '../shared/components/not-found/not-found.component';\nimport { ECLGraphComponent } from './graph/graph.component';\n\ntype PathMatch = 'full' | 'prefix' | undefined;\n\nexport const EclRoutes: Routes = [\n {\n path: '', component: ECLRootComponent,\n children: [\n { path: '', pathMatch: <PathMatch>'full', redirectTo: 'home' },\n { path: 'home', component: ECLHomeComponent, canActivate: [ECLUnlockedGuard] },\n {\n path: 'onchain', component: ECLOnChainComponent, canActivate: [ECLUnlockedGuard], children: [\n { path: '', pathMatch: <PathMatch>'full', redirectTo: 'receive' },\n { path: 'receive', component: ECLOnChainReceiveComponent, canActivate: [ECLUnlockedGuard] },\n { path: 'send', component: ECLOnChainSendComponent, canActivate: [ECLUnlockedGuard] }\n ]\n },\n {\n path: 'connections', component: ECLConnectionsComponent, canActivate: [ECLUnlockedGuard], children: [\n { path: '', pathMatch: <PathMatch>'full', redirectTo: 'channels' },\n {\n path: 'channels', component: ECLChannelsTablesComponent, canActivate: [ECLUnlockedGuard], children: [\n { path: '', pathMatch: <PathMatch>'full', redirectTo: 'open' },\n { path: 'open', component: ECLChannelOpenTableComponent, canActivate: [ECLUnlockedGuard] },\n { path: 'pending', component: ECLChannelPendingTableComponent, canActivate: [ECLUnlockedGuard] },\n { path: 'inactive', component: ECLChannelInactiveTableComponent, canActivate: [ECLUnlockedGuard] }\n ]\n },\n { path: 'peers', component: ECLPeersComponent, data: { sweepAll: false }, canActivate: [ECLUnlockedGuard] }\n ]\n },\n {\n path: 'transactions', component: ECLTransactionsComponent, canActivate: [ECLUnlockedGuard], children: [\n { path: '', pathMatch: <PathMatch>'full', redirectTo: 'payments' },\n { path: 'payments', component: ECLLightningPaymentsComponent, canActivate: [ECLUnlockedGuard] },\n { path: 'invoices', component: ECLLightningInvoicesComponent, canActivate: [ECLUnlockedGuard] }\n ]\n },\n {\n path: 'routing', component: ECLRoutingComponent, canActivate: [ECLUnlockedGuard], children: [\n { path: '', pathMatch: <PathMatch>'full', redirectTo: 'forwardinghistory' },\n { path: 'forwardinghistory', component: ECLForwardingHistoryComponent, canActivate: [ECLUnlockedGuard] },\n { path: 'peers', component: ECLRoutingPeersComponent, canActivate: [ECLUnlockedGuard] }\n ]\n },\n {\n path: 'reports', component: ECLReportsComponent, canActivate: [ECLUnlockedGuard], children: [\n { path: '', pathMatch: <PathMatch>'full', redirectTo: 'routingreport' },\n { path: 'routingreport', component: ECLRoutingReportComponent, canActivate: [ECLUnlockedGuard] },\n { path: 'transactions', component: ECLTransactionsReportComponent, canActivate: [ECLUnlockedGuard] }\n ]\n },\n {\n path: 'graph', component: ECLGraphComponent, canActivate: [ECLUnlockedGuard], children: [\n { path: '', pathMatch: <PathMatch>'full', redirectTo: 'lookups' },\n { path: 'lookups', component: ECLLookupsComponent, canActivate: [ECLUnlockedGuard] },\n { path: 'queryroutes', component: ECLQueryRoutesComponent, canActivate: [ECLUnlockedGuard] }\n ]\n },\n { path: '**', component: NotFoundComponent }\n ]\n }\n];\n\nexport const ECLRouting: ModuleWithProviders<RouterModule> = RouterModule.forChild(EclRoutes);\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nimport { ECLRouting } from './ecl.routing';\nimport { SharedModule } from '../shared/shared.module';\n\nimport { ECLRootComponent } from './ecl-root.component';\nimport { ECLHomeComponent } from './home/home.component';\nimport { ECLNodeInfoComponent } from './home/node-info/node-info.component';\nimport { ECLBalancesInfoComponent } from './home/balances-info/balances-info.component';\nimport { ECLFeeInfoComponent } from './home/fee-info/fee-info.component';\nimport { ECLChannelStatusInfoComponent } from './home/channel-status-info/channel-status-info.component';\nimport { ECLChannelCapacityInfoComponent } from './home/channel-capacity-info/channel-capacity-info.component';\nimport { ECLChannelLiquidityInfoComponent } from './home/channel-liquidity-info/channel-liquidity-info.component';\nimport { ECLOnChainComponent } from './on-chain/on-chain.component';\nimport { ECLOnChainReceiveComponent } from './on-chain/on-chain-receive/on-chain-receive.component';\nimport { ECLOnChainTransactionHistoryComponent } from './on-chain/on-chain-transaction-history/on-chain-transaction-history.component';\nimport { ECLConnectionsComponent } from './peers-channels/connections.component';\nimport { ECLPeersComponent } from './peers-channels/peers/peers.component';\nimport { ECLChannelsTablesComponent } from './peers-channels/channels/channels-tables/channels-tables.component';\nimport { ECLChannelOpenTableComponent } from './peers-channels/channels/channels-tables/channel-open-table/channel-open-table.component';\nimport { ECLChannelPendingTableComponent } from './peers-channels/channels/channels-tables/channel-pending-table/channel-pending-table.component';\nimport { ECLChannelInactiveTableComponent } from './peers-channels/channels/channels-tables/channel-inactive-table/channel-inactive-table.component';\nimport { ECLTransactionsComponent } from './transactions/transactions.component';\nimport { ECLQueryRoutesComponent } from './graph/query-routes/query-routes.component';\nimport { ECLLightningPaymentsComponent } from './transactions/payments/lightning-payments.component';\nimport { ECLLightningInvoicesComponent } from './transactions/invoices/lightning-invoices.component';\nimport { ECLRoutingComponent } from './routing/routing.component';\nimport { ECLForwardingHistoryComponent } from './routing/forwarding-history/forwarding-history.component';\nimport { ECLRoutingPeersComponent } from './routing/routing-peers/routing-peers.component';\nimport { ECLLookupsComponent } from './graph/lookups/lookups.component';\nimport { ECLNodeLookupComponent } from './graph/lookups/node-lookup/node-lookup.component';\nimport { ECLGraphComponent } from './graph/graph.component';\nimport { ECLReportsComponent } from './reports/reports.component';\nimport { ECLRoutingReportComponent } from './reports/routing/routing-report.component';\nimport { ECLTransactionsReportComponent } from './reports/transactions/transactions-report.component';\nimport { ECLOnChainSendComponent } from './on-chain/on-chain-send/on-chain-send.component';\nimport { ECLInvoiceInformationComponent } from './transactions/invoice-information-modal/invoice-information.component';\nimport { ECLPaymentInformationComponent } from './transactions/payment-information-modal/payment-information.component';\nimport { ECLOpenChannelComponent } from './peers-channels/channels/open-channel-modal/open-channel.component';\nimport { ECLConnectPeerComponent } from './peers-channels/connect-peer/connect-peer.component';\nimport { ECLLightningSendPaymentsComponent } from './transactions/send-payment-modal/send-payment.component';\nimport { ECLCreateInvoiceComponent } from './transactions/create-invoice-modal/create-invoice.component';\nimport { ECLOnChainSendModalComponent } from './on-chain/on-chain-send-modal/on-chain-send-modal.component';\nimport { ECLChannelInformationComponent } from './peers-channels/channels/channel-information-modal/channel-information.component';\n\nimport { ECLUnlockedGuard } from '../shared/services/auth.guard';\n\n@NgModule({\n imports: [\n CommonModule,\n SharedModule,\n ECLRouting\n ],\n declarations: [\n ECLRootComponent,\n ECLHomeComponent,\n ECLNodeInfoComponent,\n ECLBalancesInfoComponent,\n ECLFeeInfoComponent,\n ECLChannelStatusInfoComponent,\n ECLChannelCapacityInfoComponent,\n ECLChannelLiquidityInfoComponent,\n ECLOnChainComponent,\n ECLOnChainReceiveComponent,\n ECLOnChainTransactionHistoryComponent,\n ECLPeersComponent,\n ECLConnectionsComponent,\n ECLChannelsTablesComponent,\n ECLChannelOpenTableComponent,\n ECLChannelPendingTableComponent,\n ECLChannelInactiveTableComponent,\n ECLRoutingComponent,\n ECLForwardingHistoryComponent,\n ECLRoutingPeersComponent,\n ECLTransactionsComponent,\n ECLQueryRoutesComponent,\n ECLLightningPaymentsComponent,\n ECLLightningInvoicesComponent,\n ECLLookupsComponent,\n ECLNodeLookupComponent,\n ECLGraphComponent,\n ECLReportsComponent,\n ECLRoutingReportComponent,\n ECLTransactionsReportComponent,\n ECLOnChainSendComponent,\n ECLInvoiceInformationComponent,\n ECLPaymentInformationComponent,\n ECLOpenChannelComponent,\n ECLConnectPeerComponent,\n ECLLightningSendPaymentsComponent,\n ECLCreateInvoiceComponent,\n ECLOnChainSendModalComponent,\n ECLChannelInformationComponent\n ],\n providers: [\n ECLUnlockedGuard\n ],\n bootstrap: [ECLRootComponent]\n})\nexport class ECLModule { }\n"],"x_google_ignoreList":[]}