diff --git a/backend/controllers/shared/pageSettings.js b/backend/controllers/shared/pageSettings.js index 44d063a7..abfc2ef2 100644 --- a/backend/controllers/shared/pageSettings.js +++ b/backend/controllers/shared/pageSettings.js @@ -19,53 +19,32 @@ export const savePageSettings = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Page Settings', msg: 'Saving Page Settings..' }); req.body = [ { - pageId: "payments", tables: [ { + tableId: "payments", recordsPerPage: 25, sortBy: "created_at", sortOrder: "Ascending", showColumns: [ - "created_at", - "type", - "payment_hash", - "msatoshi_sent", "msatoshi", ], }, - ], - }, - { - pageId: "invoices1", - tables: [ - { - tableId: "invoices1", - recordsPerPage: 10, - showColumns: [ - "msatoshi_received", - ], - }, - ], - }, - { - tables: [ { - tableId: "invoices2", - sortBy: "expires_at", - sortOrder: "Descending", + tableId: "payments2", + sortBy: "created_at", + sortOrder: "Ascending", showColumns: [ - "expires_at", - "paid_at", + "created_at", "type", - "description", + "payment_hash", + "msatoshi_sent", "msatoshi", - "msatoshi_received", ], }, ], }, { - pageId: "invoices3", + pageId: "invoices", tables: [ { tableId: "invoices3", @@ -92,11 +71,4 @@ export const savePageSettings = (req, res, next) => { const err = common.handleError(errRes, 'Page Settings', 'Page Settings Update Error', req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); }); - // return databaseService.insert(req.session.selectedNode, CollectionsEnum.PAGE_SETTINGS, req.body).then((insertedSettings) => { - // logger.log({ level: 'DEBUG', fileName: 'Page Settings', msg: 'Page Settings Updated', data: insertedSettings }); - // return res.status(201).json(true); - // }).catch((errRes) => { - // const err = common.handleError(errRes, 'Page Settings', 'Page Settings Update Error', req.session.selectedNode); - // return res.status(err.statusCode).json({ message: err.message, error: err.error }); - // }); }; diff --git a/backend/models/database.model.js b/backend/models/database.model.js index c2c40302..1d3da57c 100644 --- a/backend/models/database.model.js +++ b/backend/models/database.model.js @@ -75,45 +75,51 @@ export class PageSettings { } } export const validatePageSettings = (documentToValidate) => { - const errorMessages = documentToValidate.reduce((docAcc, doc, pageIdx) => { - let newDocMsgs = ''; - if (!doc.hasOwnProperty(CollectionFieldsEnum.PAGE_ID)) { - newDocMsgs = newDocMsgs + ' ' + CollectionFieldsEnum.PAGE_ID + ' is mandatory.'; + let errorMessages = ''; + if (!documentToValidate.hasOwnProperty(CollectionFieldsEnum.PAGE_ID)) { + errorMessages = errorMessages + CollectionFieldsEnum.PAGE_ID + ' is mandatory.'; + } + if (!documentToValidate.hasOwnProperty(CollectionFieldsEnum.TABLES)) { + errorMessages = errorMessages + CollectionFieldsEnum.TABLES + ' is mandatory.'; + } + const tablesMessages = documentToValidate.tables.reduce((tableAcc, table, tableIdx) => { + let errMsg = ''; + if (!table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID)) { + errMsg = errMsg + CollectionFieldsEnum.TABLE_ID + ' is mandatory.'; + } + if (!table.hasOwnProperty(CollectionFieldsEnum.SORT_BY)) { + errMsg = errMsg + CollectionFieldsEnum.SORT_BY + ' is mandatory.'; + } + if (!table.hasOwnProperty(CollectionFieldsEnum.SORT_ORDER)) { + errMsg = errMsg + CollectionFieldsEnum.SORT_ORDER + ' is mandatory.'; + } + if (!table.hasOwnProperty(CollectionFieldsEnum.RECORDS_PER_PAGE)) { + errMsg = errMsg + CollectionFieldsEnum.RECORDS_PER_PAGE + ' is mandatory.'; } - if (!doc.hasOwnProperty(CollectionFieldsEnum.TABLES)) { - newDocMsgs = newDocMsgs + ' ' + CollectionFieldsEnum.TABLES + ' is mandatory.'; + if (!table.hasOwnProperty(CollectionFieldsEnum.SHOW_COLUMNS)) { + errMsg = errMsg + CollectionFieldsEnum.SHOW_COLUMNS + ' is mandatory.'; } - newDocMsgs = newDocMsgs + ' ' + doc.tables.reduce((tableAcc, table, tableIdx) => { - if (!table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.TABLE_ID + ' is mandatory.'; - } - if (!table.hasOwnProperty(CollectionFieldsEnum.SORT_BY)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.SORT_BY + ' is mandatory.'; - } - if (!table.hasOwnProperty(CollectionFieldsEnum.SORT_ORDER)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.SORT_ORDER + ' is mandatory.'; - } - if (!table.hasOwnProperty(CollectionFieldsEnum.RECORDS_PER_PAGE)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.RECORDS_PER_PAGE + ' is mandatory.'; - } - if (!table.hasOwnProperty(CollectionFieldsEnum.SHOW_COLUMNS)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.SHOW_COLUMNS + ' is mandatory.'; - } - if (table[CollectionFieldsEnum.SHOW_COLUMNS].length < 2) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.SHOW_COLUMNS + ' should have at least 2 fields.'; - } - tableAcc = tableAcc.trim() !== '' ? ('table ' + (table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID) ? table[CollectionFieldsEnum.TABLE_ID] : (tableIdx + 1)) + tableAcc) : ''; - return tableAcc; - }, ''); - if (newDocMsgs.trim() !== '') { - docAcc = docAcc + '\nFor page ' + (doc.hasOwnProperty(CollectionFieldsEnum.PAGE_ID) ? doc[CollectionFieldsEnum.PAGE_ID] : (pageIdx + 1)) + newDocMsgs; + if (table[CollectionFieldsEnum.SHOW_COLUMNS].length < 2) { + errMsg = errMsg + CollectionFieldsEnum.SHOW_COLUMNS + ' should have at least 2 fields.'; } - return docAcc; - }, ''); - if (errorMessages !== '') { - return ({ isValid: false, error: errorMessages }); + if (errMsg.trim() !== '') { + tableAcc.push({ table: (table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID) ? table[CollectionFieldsEnum.TABLE_ID] : (tableIdx + 1)), message: errMsg }); + } + return tableAcc; + }, []); + if (errorMessages.trim() === '' && tablesMessages.length && tablesMessages.length === 0) { + return ({ isValid: true }); + } + else { + const errObj = { page: (documentToValidate.hasOwnProperty(CollectionFieldsEnum.PAGE_ID) ? documentToValidate[CollectionFieldsEnum.PAGE_ID] : 'Unknown') }; + if (errorMessages.trim() !== '') { + errObj['message'] = errorMessages; + } + if (tablesMessages.length && tablesMessages.length > 0) { + errObj['tables'] = tablesMessages; + } + return ({ isValid: false, error: JSON.stringify(errObj) }); } - return ({ isValid: true }); }; export var CollectionsEnum; (function (CollectionsEnum) { diff --git a/server/controllers/shared/pageSettings.ts b/server/controllers/shared/pageSettings.ts index 5bb277aa..1b7dfbcc 100644 --- a/server/controllers/shared/pageSettings.ts +++ b/server/controllers/shared/pageSettings.ts @@ -22,53 +22,32 @@ export const savePageSettings = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Page Settings', msg: 'Saving Page Settings..' }); req.body = [ { - pageId: "payments", tables: [ { + tableId: "payments", recordsPerPage: 25, sortBy: "created_at", sortOrder: "Ascending", showColumns: [ - "created_at", - "type", - "payment_hash", - "msatoshi_sent", "msatoshi", ], }, - ], - }, - { - pageId: "invoices1", - tables: [ - { - tableId: "invoices1", - recordsPerPage: 10, - showColumns: [ - "msatoshi_received", - ], - }, - ], - }, - { - tables: [ { - tableId: "invoices2", - sortBy: "expires_at", - sortOrder: "Descending", + tableId: "payments2", + sortBy: "created_at", + sortOrder: "Ascending", showColumns: [ - "expires_at", - "paid_at", + "created_at", "type", - "description", + "payment_hash", + "msatoshi_sent", "msatoshi", - "msatoshi_received", ], }, ], }, { - pageId: "invoices3", + pageId: "invoices", tables: [ { tableId: "invoices3", @@ -95,11 +74,4 @@ export const savePageSettings = (req, res, next) => { const err = common.handleError(errRes, 'Page Settings', 'Page Settings Update Error', req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); }); - // return databaseService.insert(req.session.selectedNode, CollectionsEnum.PAGE_SETTINGS, req.body).then((insertedSettings) => { - // logger.log({ level: 'DEBUG', fileName: 'Page Settings', msg: 'Page Settings Updated', data: insertedSettings }); - // return res.status(201).json(true); - // }).catch((errRes) => { - // const err = common.handleError(errRes, 'Page Settings', 'Page Settings Update Error', req.session.selectedNode); - // return res.status(err.statusCode).json({ message: err.message, error: err.error }); - // }); }; diff --git a/server/models/database.model.ts b/server/models/database.model.ts index e3714a0f..e868696d 100644 --- a/server/models/database.model.ts +++ b/server/models/database.model.ts @@ -86,45 +86,50 @@ export class PageSettings { } export const validatePageSettings = (documentToValidate): any => { - const errorMessages = documentToValidate.reduce((docAcc, doc: PageSettings, pageIdx) => { - let newDocMsgs = ''; - if (!doc.hasOwnProperty(CollectionFieldsEnum.PAGE_ID)) { - newDocMsgs = newDocMsgs + ' ' + CollectionFieldsEnum.PAGE_ID + ' is mandatory.'; + let errorMessages = ''; + if (!documentToValidate.hasOwnProperty(CollectionFieldsEnum.PAGE_ID)) { + errorMessages = errorMessages + CollectionFieldsEnum.PAGE_ID + ' is mandatory.'; + } + if (!documentToValidate.hasOwnProperty(CollectionFieldsEnum.TABLES)) { + errorMessages = errorMessages + CollectionFieldsEnum.TABLES + ' is mandatory.'; + } + const tablesMessages = documentToValidate.tables.reduce((tableAcc, table: TableSetting, tableIdx) => { + let errMsg = ''; + if (!table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID)) { + errMsg = errMsg + CollectionFieldsEnum.TABLE_ID + ' is mandatory.'; + } + if (!table.hasOwnProperty(CollectionFieldsEnum.SORT_BY)) { + errMsg = errMsg + CollectionFieldsEnum.SORT_BY + ' is mandatory.'; + } + if (!table.hasOwnProperty(CollectionFieldsEnum.SORT_ORDER)) { + errMsg = errMsg + CollectionFieldsEnum.SORT_ORDER + ' is mandatory.'; + } + if (!table.hasOwnProperty(CollectionFieldsEnum.RECORDS_PER_PAGE)) { + errMsg = errMsg + CollectionFieldsEnum.RECORDS_PER_PAGE + ' is mandatory.'; } - if (!doc.hasOwnProperty(CollectionFieldsEnum.TABLES)) { - newDocMsgs = newDocMsgs + ' ' + CollectionFieldsEnum.TABLES + ' is mandatory.'; + if (!table.hasOwnProperty(CollectionFieldsEnum.SHOW_COLUMNS)) { + errMsg = errMsg + CollectionFieldsEnum.SHOW_COLUMNS + ' is mandatory.'; } - newDocMsgs = newDocMsgs + ' ' + doc.tables.reduce((tableAcc, table: TableSetting, tableIdx) => { - if (!table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.TABLE_ID + ' is mandatory.'; - } - if (!table.hasOwnProperty(CollectionFieldsEnum.SORT_BY)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.SORT_BY + ' is mandatory.'; - } - if (!table.hasOwnProperty(CollectionFieldsEnum.SORT_ORDER)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.SORT_ORDER + ' is mandatory.'; - } - if (!table.hasOwnProperty(CollectionFieldsEnum.RECORDS_PER_PAGE)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.RECORDS_PER_PAGE + ' is mandatory.'; - } - if (!table.hasOwnProperty(CollectionFieldsEnum.SHOW_COLUMNS)) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.SHOW_COLUMNS + ' is mandatory.'; - } - if (table[CollectionFieldsEnum.SHOW_COLUMNS].length < 2) { - tableAcc = tableAcc + ' ' + CollectionFieldsEnum.SHOW_COLUMNS + ' should have at least 2 fields.'; - } - tableAcc = tableAcc.trim() !== '' ? ('table ' + (table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID) ? table[CollectionFieldsEnum.TABLE_ID] : (tableIdx + 1)) + tableAcc) : ''; - return tableAcc; - }, ''); - if (newDocMsgs.trim() !== '') { - docAcc = docAcc + '\nFor page ' + (doc.hasOwnProperty(CollectionFieldsEnum.PAGE_ID) ? doc[CollectionFieldsEnum.PAGE_ID] : (pageIdx + 1)) + newDocMsgs; + if (table[CollectionFieldsEnum.SHOW_COLUMNS].length < 2) { + errMsg = errMsg + CollectionFieldsEnum.SHOW_COLUMNS + ' should have at least 2 fields.'; } - return docAcc; - }, ''); - if (errorMessages !== '') { - return ({ isValid: false, error: errorMessages }); + if (errMsg.trim() !== '') { + tableAcc.push({ table: (table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID) ? table[CollectionFieldsEnum.TABLE_ID] : (tableIdx + 1)), message: errMsg }); + } + return tableAcc; + }, []); + if (errorMessages.trim() === '' && tablesMessages.length && tablesMessages.length === 0) { + return ({ isValid: true }); + } else { + const errObj = { page: (documentToValidate.hasOwnProperty(CollectionFieldsEnum.PAGE_ID) ? documentToValidate[CollectionFieldsEnum.PAGE_ID] : 'Unknown') }; + if (errorMessages.trim() !== '') { + errObj['message'] = errorMessages; + } + if (tablesMessages.length && tablesMessages.length > 0) { + errObj['tables'] = tablesMessages; + } + return ({ isValid: false, error: JSON.stringify(errObj) }); } - return ({ isValid: true }); }; export enum CollectionsEnum { diff --git a/src/app/lnd/transactions/send-payment-modal/send-payment.component.ts b/src/app/lnd/transactions/send-payment-modal/send-payment.component.ts index 135a956c..bdecf351 100644 --- a/src/app/lnd/transactions/send-payment-modal/send-payment.component.ts +++ b/src/app/lnd/transactions/send-payment-modal/send-payment.component.ts @@ -175,7 +175,7 @@ export class LightningSendPaymentsComponent implements OnInit, OnDestroy { this.selectedChannelCtrl.disable(); } this.zeroAmtInvoice = false; - if (this.selNode.fiatConversion) { + if (this.selNode && this.selNode.fiatConversion) { this.commonService.convertCurrency(+this.paymentDecoded.num_satoshis, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : 'BTC'), this.selNode.fiatConversion). pipe(takeUntil(this.unSubs[4])). subscribe({ diff --git a/src/app/shared/components/node-config/page-settings/page-settings.component.html b/src/app/shared/components/node-config/page-settings/page-settings.component.html index c9c029b3..f49f39fc 100644 --- a/src/app/shared/components/node-config/page-settings/page-settings.component.html +++ b/src/app/shared/components/node-config/page-settings/page-settings.component.html @@ -4,43 +4,54 @@ Page Settings - - - {{page.pageId | titlecase}} - -
-
- - - - {{pageSizeOption}} - - - - - - - {{field | camelcaseWithReplace:'_'}} - - - - - - - {{so}} - - - - - - - {{field | camelcaseWithReplace:'_'}} - - - +
+ + Page {{errorMessage.page | titlecase}} + error{{errorMessage.message}} + + errorTable {{table.table | titlecase}} {{table.message}} + + +
+
+ + + {{page.pageId | titlecase}} + +
+
+ + + + {{pageSizeOption}} + + + + + + + {{field | camelcaseWithReplace:'_'}} + + + + + + + {{so}} + + + + + + + {{field | camelcaseWithReplace:'_'}} + + + +
-
- + +
diff --git a/src/app/shared/components/node-config/page-settings/page-settings.component.ts b/src/app/shared/components/node-config/page-settings/page-settings.component.ts index e43dbd7c..b7fb890b 100644 --- a/src/app/shared/components/node-config/page-settings/page-settings.component.ts +++ b/src/app/shared/components/node-config/page-settings/page-settings.component.ts @@ -1,16 +1,18 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { filter, takeUntil } from 'rxjs/operators'; import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; import { faPenRuler } from '@fortawesome/free-solid-svg-icons'; -import { CLN_DEFAULT_PAGE_SETTINGS, CLN_TABLE_FIELDS_DEF, PAGE_SIZE_OPTIONS, ScreenSizeEnum, SORT_ORDERS } from '../../../services/consts-enums-functions'; +import { APICallStatusEnum, CLNActions, CLN_DEFAULT_PAGE_SETTINGS, CLN_TABLE_FIELDS_DEF, PAGE_SIZE_OPTIONS, ScreenSizeEnum, SORT_ORDERS } from '../../../services/consts-enums-functions'; import { LoggerService } from '../../../services/logger.service'; import { CommonService } from '../../../services/common.service'; import { RTLState } from '../../../../store/rtl.state'; import { TableSetting, PageSettingsCLN } from '../../../models/pageSettings'; import { clnPageSettings } from '../../../../cln/store/cln.selector'; import { savePageSettings } from '../../../../cln/store/cln.actions'; +import { ApiCallStatusPayload } from '../../../models/apiCallsPayload'; @Component({ selector: 'rtl-page-settings', @@ -27,18 +29,33 @@ export class PageSettingsComponent implements OnInit, OnDestroy { public initialPageSettings: PageSettingsCLN[] = CLN_DEFAULT_PAGE_SETTINGS; public tableFieldsDef = CLN_TABLE_FIELDS_DEF; public sortOrders = SORT_ORDERS; - unSubs: Array> = [new Subject(), new Subject()]; + public apiCallStatus: ApiCallStatusPayload | null = null; + public apiCallStatusEnum = APICallStatusEnum; + public errorMessage: any = null; + unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private commonService: CommonService, private store: Store) { + constructor(private logger: LoggerService, private commonService: CommonService, private store: Store, private actions: Actions) { this.screenSize = this.commonService.getScreenSize(); } ngOnInit() { - this.store.select(clnPageSettings).pipe(takeUntil(this.unSubs[0])).subscribe((settings) => { - this.pageSettings = settings.pageSettings; - this.initialPageSettings = JSON.parse(JSON.stringify(settings.pageSettings)); - this.logger.info(settings); - }); + this.store.select(clnPageSettings).pipe(takeUntil(this.unSubs[0])). + subscribe((settings: { pageSettings: PageSettingsCLN[], apiCallStatus: ApiCallStatusPayload }) => { + this.errorMessage = null; + this.apiCallStatus = settings.apiCallStatus; + if (this.apiCallStatus.status === APICallStatusEnum.ERROR) { + this.errorMessage = this.apiCallStatus.message || null; + } + this.pageSettings = settings.pageSettings; + this.initialPageSettings = JSON.parse(JSON.stringify(settings.pageSettings)); + this.logger.info(settings); + }); + this.actions.pipe(takeUntil(this.unSubs[1]), filter((action) => action.type === CLNActions.UPDATE_API_CALL_STATUS_CLN || action.type === CLNActions.SAVE_PAGE_SETTINGS_CLN)). + subscribe((action: any) => { + if (action.type === CLNActions.UPDATE_API_CALL_STATUS_CLN && action.payload.status === APICallStatusEnum.ERROR && action.payload.action === 'SavePageSettings') { + this.errorMessage = JSON.parse(action.payload.message); + } + }); } onShowColumnsChange(table: TableSetting) { @@ -51,10 +68,12 @@ export class PageSettingsComponent implements OnInit, OnDestroy { if (this.pageSettings.reduce((pacc, page) => pacc || (page.tables.reduce((acc, table) => !(table.recordsPerPage && table.sortBy && table.sortOrder && table.showColumns && table.showColumns.length >= 3), false)), false)) { return true; } + this.errorMessage = ''; this.store.dispatch(savePageSettings({ payload: this.pageSettings })); } onResetPageSettings() { + this.errorMessage = null; this.pageSettings = this.initialPageSettings; }