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
543 KiB
Plaintext

{"version":3,"file":"src_app_eclair_ecl_module_ts.bf14f5e7d19c13dd.js","mappings":"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","names":["i0","ECLRootComponent","constructor","router","this","events","subscribe","event","NavigationStart","loading","NavigationEnd","NavigationCancel","NavigationError","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","active","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","MAT_SELECT_CONFIG","useValue","overlayPanelClass","MatPaginatorIntl","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","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","start","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=\"8\" 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=\"8\" 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 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 fxLayout=\"column\" fxFlex=\"100\">\n <mat-label>Payment Request</mat-label>\n <textarea #paymentReq=\"ngModel\" autoFocus matInput 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 <mat-label>Amount (Sats)</mat-label>\n <input #paymentAmt=\"ngModel\" matInput 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 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 fxLayout=\"column\" fxFlex=\"100\">\n <mat-label>Payment Request</mat-label>\n <textarea #paymentReq=\"ngModel\" matInput 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput name=\"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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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 center\" class=\"part-group-head\">\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\" class=\"part-group-details\" fxLayoutAlign=\"end center\">\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';\nimport { MAT_SELECT_CONFIG } from '@angular/material/select';\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: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'rtl-select-overlay' } },\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) / 14) + '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({ active: this.tableSetting.sortBy, direction: 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 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 fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start end\">\n <mat-label>Description</mat-label>\n <input matInput autoFocus 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 fxLayout=\"column\" fxFlex=\"40\">\n <mat-label>Amount</mat-label>\n <input matInput 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 fxLayout=\"column\" fxFlex=\"30\">\n <mat-label>Expiry</mat-label>\n <input matInput 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 fxLayout=\"column\" 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 fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\">\n <mat-label>Description</mat-label>\n <input matInput 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 fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start end\">\n <mat-label>Amount</mat-label>\n <input #invcVal=\"ngModel\" matInput 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput name=\"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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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';\nimport { MAT_SELECT_CONFIG } from '@angular/material/select';\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: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'rtl-select-overlay' } },\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) / 14) + '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({ active: this.tableSetting.sortBy, direction: 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=\"row\" fxFlex=\"100\" fxLayoutAlign=\"space-between start\">\n <mat-tab-group mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" fxLayout=\"column\" class=\"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-group>\n <div class=\"underline\">\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 </div>\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 = '390px';\n public merchantCardHeight = '62px';\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 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 fxLayout=\"column\" fxFlex=\"55\">\n <mat-label>Bitcoin Address</mat-label>\n <input #addrs=\"ngModel\" matInput autoFocus 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 fxLayout=\"column\" fxFlex=\"30\">\n <mat-label>Amount</mat-label>\n <input #amnt=\"ngModel\" matInput 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 fxLayout=\"column\" 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 fxLayout=\"column\" fxFlex=\"48\" fxLayoutAlign=\"start center\">\n <mat-label>Target Confirmation Blocks</mat-label>\n <input #blocks=\"ngModel\" matInput 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput name=\"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\" [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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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';\nimport { MAT_SELECT_CONFIG } from '@angular/material/select';\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: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'rtl-select-overlay' } },\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) / 14) + '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 && this.sort && this.paginator) {\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({ active: this.tableSetting.sortBy, direction: 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 mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" [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 <div fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"space-between stretch\" class=\"padding-gap-x-large\">\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 mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" [(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 mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" [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 <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 mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" 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 </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\" 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 fxLayout=\"column\" fxFlex=\"100\" fxLayoutAlign=\"start end\" [ngClass]=\"{'mt-1': true, 'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}\">\n <mat-label>{{lookupFields[selectedFieldId]?.placeholder || 'Lookup Key'}}</mat-label>\n <input #key matInput name=\"lookupKey\" tabindex=\"2\" required [formControl]=\"lookupKeyCtrl\">\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 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 <mat-label>Peer Alias</mat-label>\n <input type=\"text\" 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 fxLayout=\"column\" fxFlex=\"70\" fxLayoutAlign=\"start end\">\n <mat-label>Amount</mat-label>\n <input #amount=\"ngModel\" matInput 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Fee (Sats/vByte)</mat-label>\n <input #fee=\"ngModel\" matInput 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=\"bordered-box\">\n <mat-tab-group mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" [(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 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput name=\"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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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';\nimport { MAT_SELECT_CONFIG } from '@angular/material/select';\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: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'rtl-select-overlay' } },\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) / 14) + '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 | string) {\n if (channelToUpdate !== 'all' && ((<Channel>channelToUpdate)?.state && (<Channel>channelToUpdate)?.state !== 'NORMAL')) {\n return;\n }\n const titleMsg = typeof channelToUpdate === 'string' && channelToUpdate === 'all' ? 'Update fee policy for all channels' :\n ('Update fee policy for Channel: ' + ((!(<Channel>channelToUpdate)?.alias && !(<Channel>channelToUpdate)?.shortChannelId) ? (<Channel>channelToUpdate)?.channelId :\n ((<Channel>channelToUpdate)?.alias && (<Channel>channelToUpdate)?.shortChannelId) ? (<Channel>channelToUpdate)?.alias + ' (' + (<Channel>channelToUpdate)?.shortChannelId + ')' :\n (<Channel>channelToUpdate)?.alias ? (<Channel>channelToUpdate)?.alias : (<Channel>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 (<Channel>channelToUpdate)?.feeBaseMsat !== 'undefined' ? (<Channel>channelToUpdate)?.feeBaseMsat : 1000, step: 100, width: 48 },\n { placeholder: 'Fee Rate (mili mSats)', inputType: DataTypeEnum.NUMBER, inputValue: channelToUpdate && typeof (<Channel>channelToUpdate)?.feeProportionalMillionths !== 'undefined' ? (<Channel>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: (<Channel>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: (<Channel>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({ active: this.tableSetting.sortBy, direction: 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput name=\"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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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';\nimport { MAT_SELECT_CONFIG } from '@angular/material/select';\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: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'rtl-select-overlay' } },\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) / 14) + '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({ active: this.tableSetting.sortBy, direction: 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 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 fxLayout=\"column\" fxFlex=\"100\">\n <mat-label>Lightning Address (pubkey OR pubkey@ip:port)</mat-label>\n <input autoFocus matInput 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 fxLayout=\"column\" fxFlex=\"30\" fxLayoutAlign=\"start end\">\n <mat-label>Amount</mat-label>\n <input matInput autoFocus formControlName=\"fundingAmount\" 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 fxLayout=\"column\" fxFlex=\"30\">\n <mat-label>Fee (Sats/vByte)</mat-label>\n <input matInput formControlName=\"feeRate\" 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput name=\"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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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';\nimport { MAT_SELECT_CONFIG } from '@angular/material/select';\n\n@Component({\n selector: 'rtl-ecl-peers',\n templateUrl: './peers.component.html',\n styleUrls: ['./peers.component.scss'],\n providers: [\n { provide: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'rtl-select-overlay' } },\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) / 14) + '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({ active: this.tableSetting.sortBy, direction: 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\">\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 fxLayout=\"column\" fxFlex=\"69\" fxLayoutAlign=\"start end\">\n <mat-label>Destination Node ID</mat-label>\n <input #destPubkey=\"ngModel\" matInput 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 fxLayout=\"column\" fxFlex=\"29\" fxLayoutAlign=\"start end\">\n <mat-label>Amount (Sats)</mat-label>\n <input matInput 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=\"column\" fxLayoutAlign=\"start stretch\" fxLayout.gt-sm=\"row wrap\" class=\"page-sub-title-container mt-3 mb-1\">\n <div fxFlex=\"70\" fxLayoutAlign=\"start center\">\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.gt-xs=\"row\" class=\"ellipsis-parent\" [ngStyle]=\"{'max-width': (screenSize === screenSizeEnum.XS) ? '6rem' : '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.gt-xs=\"row\" class=\"ellipsis-parent\" [ngStyle]=\"{'max-width': (screenSize === screenSizeEnum.XS) ? '6rem' : '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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput name=\"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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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';\nimport { MAT_SELECT_CONFIG } from '@angular/material/select';\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: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'rtl-select-overlay' } },\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) / 14) + '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({ active: this.tableSetting.sortBy, direction: 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" name=\"filterBy\" [(ngModel)]=\"selFilterBy\" (selectionChange)=\"selFilter=''; applyFilter()\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput name=\"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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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';\nimport { MAT_SELECT_CONFIG } from '@angular/material/select';\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: MAT_SELECT_CONFIG, useValue: { overlayPanelClass: 'rtl-select-overlay' } },\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) / 14) + '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({ active: this.tableSetting.sortBy, direction: 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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" [(ngModel)]=\"selFilterByIn\" (selectionChange)=\"selFilterIn=''; applyFilterIncoming()\" name=\"filterByIn\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns)\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput [(ngModel)]=\"selFilterIn\" (input)=\"applyFilterIncoming()\" (keyup)=\"applyFilterIncoming()\" name=\"filterin\">\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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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 fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter By</mat-label>\n <mat-select tabindex=\"1\" [(ngModel)]=\"selFilterByOut\" (selectionChange)=\"selFilterOut=''; applyFilterOutgoing()\" name=\"filterByOut\">\n <perfect-scrollbar><mat-option *ngFor=\"let column of ['all'].concat(displayedColumns.slice(0, -1))\" [value]=\"column\">{{getLabel(column)}}</mat-option></perfect-scrollbar>\n </mat-select>\n </mat-form-field>\n <mat-form-field fxLayout=\"column\" fxFlex=\"49\">\n <mat-label>Filter</mat-label>\n <input matInput [(ngModel)]=\"selFilterOut\" (input)=\"applyFilterOutgoing()\" (keyup)=\"applyFilterOutgoing()\" name=\"filterout\">\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) ? '6rem' : 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) ? '6rem' : 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-cell colspan=\"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)) / 14) + '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({ active: this.tableSetting.sortBy, direction: 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({ active: this.tableSetting.sortBy, direction: 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 mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" [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 <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 center\" [(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) / 14) + '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 mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" [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 <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":[]}