CLN Offers and Bookmarks Page Layout

CLN Offers and Bookmarks Page Layout
This commit is contained in:
ShahanaFarooqui 2022-10-17 18:33:32 -07:00
parent e7b03f4b2f
commit d98064ca2c
18 changed files with 148 additions and 83 deletions

View File

@ -11,9 +11,6 @@ export const listOfferBookmarks = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Bookmarks..' });
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 });
if (offers && offers.length > 0) {
offers = common.sortDescByKey(offers, 'lastUpdatedAt');
}
res.status(200).json(offers);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Offers', 'Offer Bookmarks Error', req.session.selectedNode);

View File

@ -13,9 +13,6 @@ export const listOfferBookmarks = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Bookmarks..' });
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 });
if (offers && offers.length > 0) {
offers = common.sortDescByKey(offers, 'lastUpdatedAt');
}
res.status(200).json(offers);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Offers', 'Offer Bookmarks Error', req.session.selectedNode);

View File

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

View File

@ -33,7 +33,7 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
@Input() numDustUTXOs = 0;
@Input() isDustUTXO = false;
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 utxos: UTXO[];
public listUTXOs: any;

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, PaymentTypes, AlertTypeEnum } 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 { OfferBookmark } from '../../../../shared/models/clnModels';
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 { RTLState } from '../../../../store/rtl.state';
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 { CLNLightningSendPaymentsComponent } from '../../send-payment-modal/send-payment.component';
import { deleteOfferBookmark } from '../../../store/cln.actions';
import { PageSettingsCLN, TableSetting } from '../../../../shared/models/pageSettings';
@Component({
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(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory;
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'offer_bookmarks', recordsPerPage: PAGE_SIZE, sortBy: 'lastUpdatedAt', sortOrder: SortOrderEnum.DESCENDING };
public displayedColumns: any[] = [];
public offersBookmarks: any;
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) {
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() {
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 }) => {
this.errorMessage = '';
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) {
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.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.offersBookmarks.sort = this.sort;
this.offersBookmarks.sort.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.offersBookmarks.filterPredicate = (Ofrbm: OfferBookmark, fltr: string) => JSON.stringify(Ofrbm).toLowerCase().includes(fltr);
this.offersBookmarks.paginator = this.paginator;
this.applyFilter();

View File

@ -15,13 +15,18 @@
<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>
<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">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Offer ID </th>
<td mat-cell *matCellDef="let offer">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '25rem' : '45rem'}">
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '25rem' : '50rem'}">
<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}}
</span>
</div>
@ -37,6 +42,16 @@
{{offer.used ? 'Yes' : 'No'}}
</td>
</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">
<th mat-header-cell *matHeaderCellDef class="px-3">
<div class="bordered-box table-actions-select">

View File

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

View File

@ -11,7 +11,7 @@ import { MatTableDataSource } from '@angular/material/table';
import * as pdfMake from 'pdfmake/build/pdfmake';
import * as pdfFonts from 'pdfmake/build/vfs_fonts';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, ScreenSizeEnum, APICallStatusEnum, AlertTypeEnum } 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 { SelNodeChild } from '../../../../shared/models/RTLconfig';
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 { openAlert, openConfirmation } from '../../../../store/rtl.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({
selector: 'rtl-cln-offers-table',
@ -41,6 +42,8 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
faHistory = faHistory;
public PAGE_ID = 'transactions';
public tableSetting: TableSetting = { tableId: 'offers', recordsPerPage: PAGE_SIZE, sortBy: 'offer_id', sortOrder: SortOrderEnum.DESCENDING };
public selNode: SelNodeChild | null = {};
public newlyAddedOfferMemo = '';
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) {
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() {
@ -85,7 +79,25 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
this.store.select(clnNodeInformation).pipe(takeUntil(this.unSubs[1])).subscribe((nodeInfo: GetInfo) => {
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 }) => {
this.errorMessage = '';
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) {
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.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.offers.sort = this.sort;
this.offers.sort.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.offers.filterPredicate = (rowData: Offer, fltr: string) => {
const newRowData = ((rowData.active) ? ' active' : ' inactive') + ((rowData.used) ? ' used' : ' unused') + ((rowData.single_use) ? ' single' : ' multiple') + JSON.stringify(rowData).toLowerCase();
if (fltr === 'active' || fltr === 'inactive' || fltr === 'used' || fltr === 'unused' || fltr === 'single' || fltr === 'multiple') {

View File

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

View File

@ -36,11 +36,11 @@ import { PageSettingsCLN, TableSetting } from '../../../shared/models/pageSettin
})
export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnDestroy {
@Input() calledFrom = 'transactions'; // Transactions/home
@Input() calledFrom = 'transactions'; // transactions/home
@ViewChild('sendPaymentForm', { static: false }) form;
@ViewChild(MatSort, { static: false }) sort: MatSort | 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 faHistory = faHistory;
public newlyAddedPayment = '';

View File

@ -11,30 +11,30 @@
</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="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-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">
{{pageSizeOption}}
</mat-option>
</mat-select>
</mat-form-field>
<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">
{{field | camelcaseWithReplace:'_'}}
</mat-option>
</mat-select>
</mat-form-field>
<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">
{{so === 'desc' ? 'Descending' : 'Ascending'}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="18">
<mat-select [(ngModel)]="table.columnSelectionSM" placeholder="Column selection (Mobile)" name="{{table.tableId}}-columns-selection-sm" tabindex="4" multiple required>
<mat-form-field fxFlex="15">
<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))">
{{field | camelcaseWithReplace:'_'}}
</mat-option>
@ -42,22 +42,23 @@
<mat-hint>Columns (mobile) should be between 1 and 2</mat-hint>
</mat-form-field>
<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))">
{{field | camelcaseWithReplace:'_'}}
</mat-option>
</mat-select>
<mat-hint>Column selection should be between 2 and {{tableFieldsDef[table.tableId].maxColumns}}</mat-hint>
</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>
<ng-container *ngIf="errorMessage && errorMessage?.page === page.pageId" [ngTemplateOutlet]="errorObjectBlock" [ngTemplateOutletContext]="{error: errorMessage}"></ng-container>
</mat-expansion-panel>
</form>
<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('default')" tabindex="7">Default Settings</button>
<button mat-flat-button color="primary" (click)="onUpdatePageSettings()" tabindex="8">Save</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="9">Reset to Default</button>
<button mat-flat-button color="primary" (click)="onUpdatePageSettings()" tabindex="10">Save</button>
</div>
</div>
<ng-template #errorObjectBlock let-error="error">

View File

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

View File

@ -73,6 +73,13 @@ export class PageSettingsComponent implements OnInit, OnDestroy {
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) {
if (prev === 'current') {
this.errorMessage = null;

View File

@ -675,16 +675,6 @@ export enum SortOrderEnum {
export const SORT_ORDERS = ['asc', 'desc'];
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: [
{ tableId: 'utxos', recordsPerPage: PAGE_SIZE, sortBy: 'blockheight', sortOrder: SortOrderEnum.DESCENDING,
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,
columnSelectionSM: ['txid', 'value'],
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 = {
utxos: {
maxColumns: 7,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved']
},
dust_utxos: {
maxColumns: 7,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved']
},
payments: {
maxColumns: 5,
allowedColumns: ['created_at', 'type', 'payment_hash', 'bolt11', 'destination', 'memo', 'label', 'msatoshi_sent', 'msatoshi']
@ -704,12 +716,12 @@ export const CLN_TABLES_DEF = {
maxColumns: 6,
allowedColumns: ['expires_at', 'paid_at', 'type', 'description', 'label', 'payment_hash', 'bolt11', 'msatoshi', 'msatoshi_received']
},
utxos: {
maxColumns: 7,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved']
offers: {
maxColumns: 4,
allowedColumns: ['offer_id', 'single_use', 'used', 'bolt12']
},
dust_utxos: {
maxColumns: 7,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved']
offer_bookmarks: {
maxColumns: 5,
allowedColumns: ['lastUpdatedAt', 'title', 'amountMSat', 'description', 'vendor', 'bolt12']
}
};