CLN Offers and Bookmarks Page Layout

CLN Offers and Bookmarks Page Layout
pull/1127/head
ShahanaFarooqui 2 years ago
parent e7b03f4b2f
commit d98064ca2c

@ -11,9 +11,6 @@ export const listOfferBookmarks = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Bookmarks..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Bookmarks..' });
databaseService.find(req.session.selectedNode, CollectionsEnum.OFFERS).then((offers) => { databaseService.find(req.session.selectedNode, CollectionsEnum.OFFERS).then((offers) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Bookmarks Received', data: offers }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Bookmarks Received', data: offers });
if (offers && offers.length > 0) {
offers = common.sortDescByKey(offers, 'lastUpdatedAt');
}
res.status(200).json(offers); res.status(200).json(offers);
}).catch((errRes) => { }).catch((errRes) => {
const err = common.handleError(errRes, 'Offers', 'Offer Bookmarks Error', req.session.selectedNode); const err = common.handleError(errRes, 'Offers', 'Offer Bookmarks Error', req.session.selectedNode);

@ -13,9 +13,6 @@ export const listOfferBookmarks = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Bookmarks..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Bookmarks..' });
databaseService.find(req.session.selectedNode, CollectionsEnum.OFFERS).then((offers: Offer[]) => { databaseService.find(req.session.selectedNode, CollectionsEnum.OFFERS).then((offers: Offer[]) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Bookmarks Received', data: offers }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Bookmarks Received', data: offers });
if (offers && offers.length > 0) {
offers = common.sortDescByKey(offers, 'lastUpdatedAt');
}
res.status(200).json(offers); res.status(200).json(offers);
}).catch((errRes) => { }).catch((errRes) => {
const err = common.handleError(errRes, 'Offers', 'Offer Bookmarks Error', req.session.selectedNode); const err = common.handleError(errRes, 'Offers', 'Offer Bookmarks Error', req.session.selectedNode);

@ -1,5 +1,3 @@
@import '../../../../shared/theme/styles/mixins.scss';
.mat-column-status { .mat-column-status {
width: 6rem; width: 6rem;
} }

@ -33,7 +33,7 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
@Input() numDustUTXOs = 0; @Input() numDustUTXOs = 0;
@Input() isDustUTXO = false; @Input() isDustUTXO = false;
public PAGE_ID = 'on-chain'; public PAGE_ID = 'on-chain';
public tableSetting: TableSetting = { tableId: 'utxos', recordsPerPage: 10, sortBy: 'status', sortOrder: SortOrderEnum.DESCENDING }; public tableSetting: TableSetting = { tableId: 'utxos', recordsPerPage: PAGE_SIZE, sortBy: 'status', sortOrder: SortOrderEnum.DESCENDING };
public displayedColumns: any[] = []; public displayedColumns: any[] = [];
public utxos: UTXO[]; public utxos: UTXO[];
public listUTXOs: any; public listUTXOs: any;

@ -1,5 +1,3 @@
@import '../../../../shared/theme/styles/mixins.scss';
.mat-column-status { .mat-column-status {
width: 2rem; width: 2rem;
} }

@ -40,8 +40,8 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined; @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined; @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory; faHistory = faHistory;
public PAGE_ID = 'invoices'; public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'invoices', recordsPerPage: 10, sortBy: 'expires_at', sortOrder: SortOrderEnum.DESCENDING }; public tableSetting: TableSetting = { tableId: 'invoices', recordsPerPage: PAGE_SIZE, sortBy: 'expires_at', sortOrder: SortOrderEnum.DESCENDING };
public selNode: SelNodeChild | null = {}; public selNode: SelNodeChild | null = {};
public newlyAddedInvoiceMemo = ''; public newlyAddedInvoiceMemo = '';
public newlyAddedInvoiceValue = 0; public newlyAddedInvoiceValue = 0;

@ -20,7 +20,7 @@
<ng-container matColumnDef="title"> <ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Title </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Title </th>
<td mat-cell *matCellDef="let offersbookmark"> <td mat-cell *matCellDef="let offersbookmark">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '20rem' : '35rem'}"> <div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '20rem' : '30rem'}">
<span class="ellipsis-child">{{offersbookmark.title}}</span> <span class="ellipsis-child">{{offersbookmark.title}}</span>
</div> </div>
</td> </td>
@ -32,13 +32,25 @@
<ng-container matColumnDef="description"> <ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Description </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Description </th>
<td mat-cell *matCellDef="let offersbookmark"> <td mat-cell *matCellDef="let offersbookmark">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '20rem' : '35rem'}"> <div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '20rem' : '30rem'}">
<span class="ellipsis-child">{{offersbookmark.description}}</span> <span class="ellipsis-child">{{offersbookmark.description}}</span>
</div> </div>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="vendor">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Vendor </th>
<td mat-cell *matCellDef="let offersbookmark">{{offersbookmark.vendor}}</td>
</ng-container>
<ng-container matColumnDef="bolt12">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="pl-1"> Invoice </th>
<td mat-cell *matCellDef="let offersbookmark" class="pl-1">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '20rem' : '30rem'}">
<span class="ellipsis-child">{{offersbookmark.bolt12}}</span>
</div>
</td>
</ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="px-3"> <th mat-header-cell *matHeaderCellDef class="pr-3">
<div class="bordered-box table-actions-select"> <div class="bordered-box table-actions-select">
<mat-select placeholder="Actions" tabindex="1" class="mr-0"> <mat-select placeholder="Actions" tabindex="1" class="mr-0">
<mat-select-trigger></mat-select-trigger> <mat-select-trigger></mat-select-trigger>
@ -46,7 +58,7 @@
</mat-select> </mat-select>
</div> </div>
</th> </th>
<td mat-cell *matCellDef="let offer" [ngClass]="{'px-3': screenSize !== screenSizeEnum.XS}" fxLayoutAlign="end center"> <td mat-cell *matCellDef="let offer" [ngClass]="{'pr-3': screenSize !== screenSizeEnum.XS}" fxLayoutAlign="end center">
<div class="bordered-box table-actions-select" fxLayoutAlign="center center"> <div class="bordered-box table-actions-select" fxLayoutAlign="center center">
<mat-select placeholder="Actions" tabindex="4" class="mr-0"> <mat-select placeholder="Actions" tabindex="4" class="mr-0">
<mat-select-trigger></mat-select-trigger> <mat-select-trigger></mat-select-trigger>

@ -1,6 +1,6 @@
.mat-column-title, .mat-column-description { .mat-column-title, .mat-column-description, .mat-column-bolt12 {
flex: 0 0 30%; flex: 0 0 20%;
width: 30%; width: 20%;
& .ellipsis-parent { & .ellipsis-parent {
display: flex; display: flex;
} }

@ -7,7 +7,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table'; import { MatTableDataSource } from '@angular/material/table';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, PaymentTypes, AlertTypeEnum } from '../../../../shared/services/consts-enums-functions'; import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, PaymentTypes, AlertTypeEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload'; import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';
import { OfferBookmark } from '../../../../shared/models/clnModels'; import { OfferBookmark } from '../../../../shared/models/clnModels';
import { LoggerService } from '../../../../shared/services/logger.service'; import { LoggerService } from '../../../../shared/services/logger.service';
@ -16,10 +16,11 @@ import { CommonService } from '../../../../shared/services/common.service';
import { RTLEffects } from '../../../../store/rtl.effects'; import { RTLEffects } from '../../../../store/rtl.effects';
import { RTLState } from '../../../../store/rtl.state'; import { RTLState } from '../../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../../store/rtl.actions'; import { openAlert, openConfirmation } from '../../../../store/rtl.actions';
import { offerBookmarks } from '../../../store/cln.selector'; import { clnPageSettings, offerBookmarks } from '../../../store/cln.selector';
import { CLNOfferInformationComponent } from '../offer-information-modal/offer-information.component'; import { CLNOfferInformationComponent } from '../offer-information-modal/offer-information.component';
import { CLNLightningSendPaymentsComponent } from '../../send-payment-modal/send-payment.component'; import { CLNLightningSendPaymentsComponent } from '../../send-payment-modal/send-payment.component';
import { deleteOfferBookmark } from '../../../store/cln.actions'; import { deleteOfferBookmark } from '../../../store/cln.actions';
import { PageSettingsCLN, TableSetting } from '../../../../shared/models/pageSettings';
@Component({ @Component({
selector: 'rtl-cln-offer-bookmarks-table', selector: 'rtl-cln-offer-bookmarks-table',
@ -34,6 +35,8 @@ export class CLNOfferBookmarksTableComponent implements OnInit, AfterViewInit, O
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined; @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined; @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory; faHistory = faHistory;
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'offer_bookmarks', recordsPerPage: PAGE_SIZE, sortBy: 'lastUpdatedAt', sortOrder: SortOrderEnum.DESCENDING };
public displayedColumns: any[] = []; public displayedColumns: any[] = [];
public offersBookmarks: any; public offersBookmarks: any;
public offersBookmarksJSONArr: OfferBookmark[] = []; public offersBookmarksJSONArr: OfferBookmark[] = [];
@ -49,19 +52,27 @@ export class CLNOfferBookmarksTableComponent implements OnInit, AfterViewInit, O
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private rtlEffects: RTLEffects) { constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private rtlEffects: RTLEffects) {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if (this.screenSize === ScreenSizeEnum.XS) {
this.displayedColumns = ['lastUpdatedAt', 'title', 'amountMSat', 'actions'];
} else if (this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = ['lastUpdatedAt', 'title', 'amountMSat', 'actions'];
} else if (this.screenSize === ScreenSizeEnum.MD) {
this.displayedColumns = ['lastUpdatedAt', 'title', 'amountMSat', 'description', 'actions'];
} else {
this.displayedColumns = ['lastUpdatedAt', 'title', 'amountMSat', 'description', 'actions'];
}
} }
ngOnInit() { ngOnInit() {
this.store.select(offerBookmarks).pipe(takeUntil(this.unSubs[0])). this.store.select(clnPageSettings).pipe(takeUntil(this.unSubs[0])).
subscribe((settings: { pageSettings: PageSettingsCLN[], apiCallStatus: ApiCallStatusPayload }) => {
this.errorMessage = '';
this.apiCallStatus = settings.apiCallStatus;
if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {
this.errorMessage = this.apiCallStatus.message || '';
}
this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || CLN_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;
if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));
} else {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));
}
this.displayedColumns.push('actions');
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.logger.info(this.displayedColumns);
});
this.store.select(offerBookmarks).pipe(takeUntil(this.unSubs[1])).
subscribe((offerBMsSeletor: { offersBookmarks: OfferBookmark[], apiCallStatus: ApiCallStatusPayload }) => { subscribe((offerBMsSeletor: { offersBookmarks: OfferBookmark[], apiCallStatus: ApiCallStatusPayload }) => {
this.errorMessage = ''; this.errorMessage = '';
this.apiCallStatus = offerBMsSeletor.apiCallStatus; this.apiCallStatus = offerBMsSeletor.apiCallStatus;
@ -106,7 +117,7 @@ export class CLNOfferBookmarksTableComponent implements OnInit, AfterViewInit, O
} }
} }
})); }));
this.rtlEffects.closeConfirm.pipe(takeUntil(this.unSubs[1])).subscribe((confirmRes) => { this.rtlEffects.closeConfirm.pipe(takeUntil(this.unSubs[2])).subscribe((confirmRes) => {
if (confirmRes) { if (confirmRes) {
this.store.dispatch(deleteOfferBookmark({ payload: { bolt12: selOffer.bolt12! } })); this.store.dispatch(deleteOfferBookmark({ payload: { bolt12: selOffer.bolt12! } }));
} }
@ -134,6 +145,7 @@ export class CLNOfferBookmarksTableComponent implements OnInit, AfterViewInit, O
this.offersBookmarks = (OffrBMs) ? new MatTableDataSource<OfferBookmark>([...OffrBMs]) : new MatTableDataSource([]); this.offersBookmarks = (OffrBMs) ? new MatTableDataSource<OfferBookmark>([...OffrBMs]) : new MatTableDataSource([]);
this.offersBookmarks.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null); this.offersBookmarks.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.offersBookmarks.sort = this.sort; this.offersBookmarks.sort = this.sort;
this.offersBookmarks.sort.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.offersBookmarks.filterPredicate = (Ofrbm: OfferBookmark, fltr: string) => JSON.stringify(Ofrbm).toLowerCase().includes(fltr); this.offersBookmarks.filterPredicate = (Ofrbm: OfferBookmark, fltr: string) => JSON.stringify(Ofrbm).toLowerCase().includes(fltr);
this.offersBookmarks.paginator = this.paginator; this.offersBookmarks.paginator = this.paginator;
this.applyFilter(); this.applyFilter();

@ -15,13 +15,18 @@
<div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container"> <div [perfectScrollbar] fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="apiCallStatus?.status === apiCallStatusEnum.INITIATED" mode="indeterminate"></mat-progress-bar>
<table mat-table #table fxFlex="100" [dataSource]="offers" matSort [ngClass]="{'overflow-auto error-border': errorMessage !== '','overflow-auto': true}"> <table mat-table #table fxFlex="100" [dataSource]="offers" matSort [ngClass]="{'overflow-auto error-border': errorMessage !== '','overflow-auto': true}">
<ng-container matColumnDef="active">
<th mat-header-cell *matHeaderCellDef mat-sort-header></th>
<td mat-cell *matCellDef="let offer">
<span *ngIf="offer.active" class="dot green" matTooltip="Active" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="!offer.active" class="dot red" matTooltip="Inactive" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
</td>
</ng-container>
<ng-container matColumnDef="offer_id"> <ng-container matColumnDef="offer_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Offer ID </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Offer ID </th>
<td mat-cell *matCellDef="let offer"> <td mat-cell *matCellDef="let offer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '25rem' : '45rem'}"> <div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '25rem' : '50rem'}">
<span class="ellipsis-child"> <span class="ellipsis-child">
<span *ngIf="offer.active" class="dot green" matTooltip="Active" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="!offer.active" class="dot red" matTooltip="Inactive" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
{{offer.offer_id}} {{offer.offer_id}}
</span> </span>
</div> </div>
@ -37,6 +42,16 @@
{{offer.used ? 'Yes' : 'No'}} {{offer.used ? 'Yes' : 'No'}}
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="bolt12">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Invoice </th>
<td mat-cell *matCellDef="let offer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '25rem' : '50rem'}">
<span class="ellipsis-child">
{{offer.bolt12}}
</span>
</div>
</td>
</ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="px-3"> <th mat-header-cell *matHeaderCellDef class="px-3">
<div class="bordered-box table-actions-select"> <div class="bordered-box table-actions-select">

@ -1,6 +1,10 @@
.mat-column-offer_id { .mat-column-active {
flex: 0 0 65%; width: 2rem;
width: 65%; }
.mat-column-offer_id, .mat-column-bolt12 {
flex: 0 0 35%;
width: 35%;
& .ellipsis-parent { & .ellipsis-parent {
display: flex; display: flex;
} }

@ -11,7 +11,7 @@ import { MatTableDataSource } from '@angular/material/table';
import * as pdfMake from 'pdfmake/build/pdfmake'; import * as pdfMake from 'pdfmake/build/pdfmake';
import * as pdfFonts from 'pdfmake/build/vfs_fonts'; import * as pdfFonts from 'pdfmake/build/vfs_fonts';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, AlertTypeEnum } from '../../../../shared/services/consts-enums-functions'; import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, AlertTypeEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload'; import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';
import { SelNodeChild } from '../../../../shared/models/RTLconfig'; import { SelNodeChild } from '../../../../shared/models/RTLconfig';
import { GetInfo, Offer, OfferRequest } from '../../../../shared/models/clnModels'; import { GetInfo, Offer, OfferRequest } from '../../../../shared/models/clnModels';
@ -26,7 +26,8 @@ import { RTLEffects } from '../../../../store/rtl.effects';
import { RTLState } from '../../../../store/rtl.state'; import { RTLState } from '../../../../store/rtl.state';
import { openAlert, openConfirmation } from '../../../../store/rtl.actions'; import { openAlert, openConfirmation } from '../../../../store/rtl.actions';
import { disableOffer } from '../../../store/cln.actions'; import { disableOffer } from '../../../store/cln.actions';
import { clnNodeInformation, clnNodeSettings, offers } from '../../../store/cln.selector'; import { clnNodeInformation, clnNodeSettings, clnPageSettings, offers } from '../../../store/cln.selector';
import { PageSettingsCLN, TableSetting } from '../../../../shared/models/pageSettings';
@Component({ @Component({
selector: 'rtl-cln-offers-table', selector: 'rtl-cln-offers-table',
@ -41,6 +42,8 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined; @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined; @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory; faHistory = faHistory;
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'offers', recordsPerPage: PAGE_SIZE, sortBy: 'offer_id', sortOrder: SortOrderEnum.DESCENDING };
public selNode: SelNodeChild | null = {}; public selNode: SelNodeChild | null = {};
public newlyAddedOfferMemo = ''; public newlyAddedOfferMemo = '';
public newlyAddedOfferValue = 0; public newlyAddedOfferValue = 0;
@ -67,15 +70,6 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private rtlEffects: RTLEffects, private dataService: DataService, private decimalPipe: DecimalPipe, private datePipe: DatePipe) { constructor(private logger: LoggerService, private store: Store<RTLState>, private commonService: CommonService, private rtlEffects: RTLEffects, private dataService: DataService, private decimalPipe: DecimalPipe, private datePipe: DatePipe) {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if (this.screenSize === ScreenSizeEnum.XS) {
this.displayedColumns = ['offer_id', 'single_use', 'actions'];
} else if (this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = ['offer_id', 'single_use', 'used', 'actions'];
} else if (this.screenSize === ScreenSizeEnum.MD) {
this.displayedColumns = ['offer_id', 'single_use', 'used', 'actions'];
} else {
this.displayedColumns = ['offer_id', 'single_use', 'used', 'actions'];
}
} }
ngOnInit() { ngOnInit() {
@ -85,7 +79,25 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
this.store.select(clnNodeInformation).pipe(takeUntil(this.unSubs[1])).subscribe((nodeInfo: GetInfo) => { this.store.select(clnNodeInformation).pipe(takeUntil(this.unSubs[1])).subscribe((nodeInfo: GetInfo) => {
this.information = nodeInfo; this.information = nodeInfo;
}); });
this.store.select(offers).pipe(takeUntil(this.unSubs[2])). this.store.select(clnPageSettings).pipe(takeUntil(this.unSubs[2])).
subscribe((settings: { pageSettings: PageSettingsCLN[], apiCallStatus: ApiCallStatusPayload }) => {
this.errorMessage = '';
this.apiCallStatus = settings.apiCallStatus;
if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {
this.errorMessage = this.apiCallStatus.message || '';
}
this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || CLN_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;
if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));
} else {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));
}
this.displayedColumns.unshift('active');
this.displayedColumns.push('actions');
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.logger.info(this.displayedColumns);
});
this.store.select(offers).pipe(takeUntil(this.unSubs[3])).
subscribe((offersSeletor: { offers: Offer[], apiCallStatus: ApiCallStatusPayload }) => { subscribe((offersSeletor: { offers: Offer[], apiCallStatus: ApiCallStatusPayload }) => {
this.errorMessage = ''; this.errorMessage = '';
this.apiCallStatus = offersSeletor.apiCallStatus; this.apiCallStatus = offersSeletor.apiCallStatus;
@ -149,7 +161,7 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
} }
} }
})); }));
this.rtlEffects.closeConfirm.pipe(takeUntil(this.unSubs[3])).subscribe((confirmRes) => { this.rtlEffects.closeConfirm.pipe(takeUntil(this.unSubs[4])).subscribe((confirmRes) => {
if (confirmRes) { if (confirmRes) {
this.store.dispatch(disableOffer({ payload: { offer_id: selOffer.offer_id! } })); this.store.dispatch(disableOffer({ payload: { offer_id: selOffer.offer_id! } }));
} }
@ -216,6 +228,7 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
this.offers = (offrs) ? new MatTableDataSource<Offer>([...offrs]) : new MatTableDataSource([]); this.offers = (offrs) ? new MatTableDataSource<Offer>([...offrs]) : new MatTableDataSource([]);
this.offers.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null); this.offers.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.offers.sort = this.sort; this.offers.sort = this.sort;
this.offers.sort.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.offers.filterPredicate = (rowData: Offer, fltr: string) => { this.offers.filterPredicate = (rowData: Offer, fltr: string) => {
const newRowData = ((rowData.active) ? ' active' : ' inactive') + ((rowData.used) ? ' used' : ' unused') + ((rowData.single_use) ? ' single' : ' multiple') + JSON.stringify(rowData).toLowerCase(); const newRowData = ((rowData.active) ? ' active' : ' inactive') + ((rowData.used) ? ' used' : ' unused') + ((rowData.single_use) ? ' single' : ' multiple') + JSON.stringify(rowData).toLowerCase();
if (fltr === 'active' || fltr === 'inactive' || fltr === 'used' || fltr === 'unused' || fltr === 'single' || fltr === 'multiple') { if (fltr === 'active' || fltr === 'inactive' || fltr === 'used' || fltr === 'unused' || fltr === 'single' || fltr === 'multiple') {

@ -1,5 +1,3 @@
@import '../../../shared/theme/styles/mixins.scss';
.mat-column-status, .mat-column-group_status { .mat-column-status, .mat-column-group_status {
width: 2rem; width: 2rem;
} }

@ -36,11 +36,11 @@ import { PageSettingsCLN, TableSetting } from '../../../shared/models/pageSettin
}) })
export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnDestroy { export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnDestroy {
@Input() calledFrom = 'transactions'; // Transactions/home @Input() calledFrom = 'transactions'; // transactions/home
@ViewChild('sendPaymentForm', { static: false }) form; @ViewChild('sendPaymentForm', { static: false }) form;
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined; @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined; @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public PAGE_ID = 'payments'; public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'created_at', sortOrder: SortOrderEnum.DESCENDING }; public tableSetting: TableSetting = { tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'created_at', sortOrder: SortOrderEnum.DESCENDING };
public faHistory = faHistory; public faHistory = faHistory;
public newlyAddedPayment = ''; public newlyAddedPayment = '';

@ -11,30 +11,30 @@
</mat-expansion-panel-header> </mat-expansion-panel-header>
<div fxLayout="column" fxLayoutAlign="start stretch" *ngFor="let table of page.tables" class="padding-gap-x-large table-setting-row"> <div fxLayout="column" fxLayoutAlign="start stretch" *ngFor="let table of page.tables" class="padding-gap-x-large table-setting-row">
<div fxLayout="row" fxLayoutAlign="space-between center"> <div fxLayout="row" fxLayoutAlign="space-between center">
<span fxFlex="10">Table {{table.tableId | camelcaseWithReplace:'_'}}: </span> <span fxFlex="10">{{table.tableId | camelcaseWithReplace:'_'}}: </span>
<mat-form-field fxFlex="10"> <mat-form-field fxFlex="10">
<mat-select [(ngModel)]="table.recordsPerPage" placeholder="Records/Page" name="{{table.tableId}}-page-size-options" tabindex="1" required> <mat-select [(ngModel)]="table.recordsPerPage" placeholder="Records/Page" name="{{table.tableId}}-page-size-options" tabindex="2" required>
<mat-option *ngFor="let pageSizeOption of pageSizeOptions" [value]="pageSizeOption"> <mat-option *ngFor="let pageSizeOption of pageSizeOptions" [value]="pageSizeOption">
{{pageSizeOption}} {{pageSizeOption}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="10"> <mat-form-field fxFlex="10">
<mat-select [(ngModel)]="table.sortBy" placeholder="Sort By" name="{{table.tableId}}-sort-by" tabindex="2" required> <mat-select [(ngModel)]="table.sortBy" placeholder="Sort By" name="{{table.tableId}}-sort-by" tabindex="3" required>
<mat-option *ngFor="let field of table.columnSelection" [value]="field"> <mat-option *ngFor="let field of table.columnSelection" [value]="field">
{{field | camelcaseWithReplace:'_'}} {{field | camelcaseWithReplace:'_'}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="10"> <mat-form-field fxFlex="10">
<mat-select [(ngModel)]="table.sortOrder" placeholder="Sort Order" name="{{table.tableId}}-sort-order" tabindex="3" required> <mat-select [(ngModel)]="table.sortOrder" placeholder="Sort Order" name="{{table.tableId}}-sort-order" tabindex="4" required>
<mat-option *ngFor="let so of sortOrders" [value]="so"> <mat-option *ngFor="let so of sortOrders" [value]="so">
{{so === 'desc' ? 'Descending' : 'Ascending'}} {{so === 'desc' ? 'Descending' : 'Ascending'}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="18"> <mat-form-field fxFlex="15">
<mat-select [(ngModel)]="table.columnSelectionSM" placeholder="Column selection (Mobile)" name="{{table.tableId}}-columns-selection-sm" tabindex="4" multiple required> <mat-select [(ngModel)]="table.columnSelectionSM" placeholder="Column selection (Mobile)" name="{{table.tableId}}-columns-selection-sm" tabindex="5" multiple required>
<mat-option *ngFor="let field of tableFieldsDef[table.tableId].allowedColumns" [value]="field" [disabled]="(table.columnSelectionSM.length <= 1 && table.columnSelectionSM.includes(field)) || (table.columnSelectionSM.length >= 2 && !table.columnSelectionSM.includes(field))"> <mat-option *ngFor="let field of tableFieldsDef[table.tableId].allowedColumns" [value]="field" [disabled]="(table.columnSelectionSM.length <= 1 && table.columnSelectionSM.includes(field)) || (table.columnSelectionSM.length >= 2 && !table.columnSelectionSM.includes(field))">
{{field | camelcaseWithReplace:'_'}} {{field | camelcaseWithReplace:'_'}}
</mat-option> </mat-option>
@ -42,22 +42,23 @@
<mat-hint>Columns (mobile) should be between 1 and 2</mat-hint> <mat-hint>Columns (mobile) should be between 1 and 2</mat-hint>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="40"> <mat-form-field fxFlex="40">
<mat-select [(ngModel)]="table.columnSelection" (selectionChange)="oncolumnSelectionChange(table)" placeholder="Column selection (Desktop)" name="{{table.tableId}}-columns-selection" tabindex="5" multiple required> <mat-select [(ngModel)]="table.columnSelection" (selectionChange)="oncolumnSelectionChange(table)" placeholder="Column selection (Desktop)" name="{{table.tableId}}-columns-selection" tabindex="6" multiple required>
<mat-option *ngFor="let field of tableFieldsDef[table.tableId].allowedColumns" [value]="field" [disabled]="(table.columnSelection.length <= 2 && table.columnSelection.includes(field)) || (table.columnSelection.length >= tableFieldsDef[table.tableId].maxColumns && !table.columnSelection.includes(field))"> <mat-option *ngFor="let field of tableFieldsDef[table.tableId].allowedColumns" [value]="field" [disabled]="(table.columnSelection.length <= 2 && table.columnSelection.includes(field)) || (table.columnSelection.length >= tableFieldsDef[table.tableId].maxColumns && !table.columnSelection.includes(field))">
{{field | camelcaseWithReplace:'_'}} {{field | camelcaseWithReplace:'_'}}
</mat-option> </mat-option>
</mat-select> </mat-select>
<mat-hint>Column selection should be between 2 and {{tableFieldsDef[table.tableId].maxColumns}}</mat-hint> <mat-hint>Column selection should be between 2 and {{tableFieldsDef[table.tableId].maxColumns}}</mat-hint>
</mat-form-field> </mat-form-field>
<button mat-icon-button color="primary" type="button" tabindex="7" (click)="onTableReset(page.pageId, table)" matTooltip="Reset to Default"><mat-icon>restore</mat-icon></button>
</div> </div>
</div> </div>
<ng-container *ngIf="errorMessage && errorMessage?.page === page.pageId" [ngTemplateOutlet]="errorObjectBlock" [ngTemplateOutletContext]="{error: errorMessage}"></ng-container> <ng-container *ngIf="errorMessage && errorMessage?.page === page.pageId" [ngTemplateOutlet]="errorObjectBlock" [ngTemplateOutletContext]="{error: errorMessage}"></ng-container>
</mat-expansion-panel> </mat-expansion-panel>
</form> </form>
<div fxLayout="row" class="mt-1"> <div fxLayout="row" class="mt-1">
<button class="mr-1" mat-stroked-button color="primary" (click)="onResetPageSettings('current')" tabindex="6">Reset</button> <button class="mr-1" mat-stroked-button color="primary" (click)="onResetPageSettings('current')" tabindex="8">Reset</button>
<button class="mr-1" mat-stroked-button color="primary" (click)="onResetPageSettings('default')" tabindex="7">Default Settings</button> <button class="mr-1" mat-stroked-button color="primary" (click)="onResetPageSettings('default')" tabindex="9">Reset to Default</button>
<button mat-flat-button color="primary" (click)="onUpdatePageSettings()" tabindex="8">Save</button> <button mat-flat-button color="primary" (click)="onUpdatePageSettings()" tabindex="10">Save</button>
</div> </div>
</div> </div>
<ng-template #errorObjectBlock let-error="error"> <ng-template #errorObjectBlock let-error="error">

@ -5,4 +5,5 @@
&:not(:first-child) { &:not(:first-child) {
margin: 3rem 0; margin: 3rem 0;
} }
} }

@ -73,6 +73,13 @@ export class PageSettingsComponent implements OnInit, OnDestroy {
this.store.dispatch(savePageSettings({ payload: this.pageSettings })); this.store.dispatch(savePageSettings({ payload: this.pageSettings }));
} }
onTableReset(currPageId: string, currTable: TableSetting) {
const pageIdx = this.pageSettings.findIndex((page) => page.pageId === currPageId);
const tableIdx = this.pageSettings[pageIdx].tables.findIndex((table) => table.tableId === currTable.tableId);
const tableToReplace = CLN_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === currPageId)?.tables.find((table) => table.tableId === currTable.tableId) || this.pageSettings.find((page) => page.pageId === currPageId)?.tables.find((table) => table.tableId === currTable.tableId);
this.pageSettings[pageIdx].tables.splice(tableIdx, 1, tableToReplace!);
}
onResetPageSettings(prev: string) { onResetPageSettings(prev: string) {
if (prev === 'current') { if (prev === 'current') {
this.errorMessage = null; this.errorMessage = null;

@ -675,16 +675,6 @@ export enum SortOrderEnum {
export const SORT_ORDERS = ['asc', 'desc']; export const SORT_ORDERS = ['asc', 'desc'];
export const CLN_DEFAULT_PAGE_SETTINGS: PageSettingsCLN[] = [ export const CLN_DEFAULT_PAGE_SETTINGS: PageSettingsCLN[] = [
{ pageId: 'payments', tables: [
{ tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'created_at', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['created_at', 'msatoshi'],
columnSelection: ['created_at', 'type', 'payment_hash', 'msatoshi_sent', 'msatoshi'] }
] },
{ pageId: 'invoices', tables: [
{ tableId: 'invoices', recordsPerPage: PAGE_SIZE, sortBy: 'expires_at', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['expires_at', 'msatoshi'],
columnSelection: ['expires_at', 'paid_at', 'type', 'description', 'msatoshi', 'msatoshi_received'] }
] },
{ pageId: 'on-chain', tables: [ { pageId: 'on-chain', tables: [
{ tableId: 'utxos', recordsPerPage: PAGE_SIZE, sortBy: 'blockheight', sortOrder: SortOrderEnum.DESCENDING, { tableId: 'utxos', recordsPerPage: PAGE_SIZE, sortBy: 'blockheight', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['txid', 'value'], columnSelectionSM: ['txid', 'value'],
@ -692,10 +682,32 @@ export const CLN_DEFAULT_PAGE_SETTINGS: PageSettingsCLN[] = [
{ tableId: 'dust_utxos', recordsPerPage: PAGE_SIZE, sortBy: 'blockheight', sortOrder: SortOrderEnum.DESCENDING, { tableId: 'dust_utxos', recordsPerPage: PAGE_SIZE, sortBy: 'blockheight', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['txid', 'value'], columnSelectionSM: ['txid', 'value'],
columnSelection: ['txid', 'output', 'value', 'blockheight'] } columnSelection: ['txid', 'output', 'value', 'blockheight'] }
] },
{ pageId: 'transactions', tables: [
{ tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'created_at', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['created_at', 'msatoshi'],
columnSelection: ['created_at', 'type', 'payment_hash', 'msatoshi_sent', 'msatoshi'] },
{ tableId: 'invoices', recordsPerPage: PAGE_SIZE, sortBy: 'expires_at', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['expires_at', 'msatoshi'],
columnSelection: ['expires_at', 'paid_at', 'type', 'description', 'msatoshi', 'msatoshi_received'] },
{ tableId: 'offers', recordsPerPage: PAGE_SIZE, sortBy: 'offer_id', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['offer_id', 'single_use'],
columnSelection: ['offer_id', 'single_use', 'used'] },
{ tableId: 'offer_bookmarks', recordsPerPage: PAGE_SIZE, sortBy: 'lastUpdatedAt', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['lastUpdatedAt', 'amountMSat'],
columnSelection: ['lastUpdatedAt', 'title', 'amountMSat', 'description'] }
] } ] }
]; ];
export const CLN_TABLES_DEF = { export const CLN_TABLES_DEF = {
utxos: {
maxColumns: 7,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved']
},
dust_utxos: {
maxColumns: 7,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved']
},
payments: { payments: {
maxColumns: 5, maxColumns: 5,
allowedColumns: ['created_at', 'type', 'payment_hash', 'bolt11', 'destination', 'memo', 'label', 'msatoshi_sent', 'msatoshi'] allowedColumns: ['created_at', 'type', 'payment_hash', 'bolt11', 'destination', 'memo', 'label', 'msatoshi_sent', 'msatoshi']
@ -704,12 +716,12 @@ export const CLN_TABLES_DEF = {
maxColumns: 6, maxColumns: 6,
allowedColumns: ['expires_at', 'paid_at', 'type', 'description', 'label', 'payment_hash', 'bolt11', 'msatoshi', 'msatoshi_received'] allowedColumns: ['expires_at', 'paid_at', 'type', 'description', 'label', 'payment_hash', 'bolt11', 'msatoshi', 'msatoshi_received']
}, },
utxos: { offers: {
maxColumns: 7, maxColumns: 4,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved'] allowedColumns: ['offer_id', 'single_use', 'used', 'bolt12']
}, },
dust_utxos: { offer_bookmarks: {
maxColumns: 7, maxColumns: 5,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved'] allowedColumns: ['lastUpdatedAt', 'title', 'amountMSat', 'description', 'vendor', 'bolt12']
} }
}; };

Loading…
Cancel
Save