CLN On-chain page settings

CLN On-chain page settings
pull/1127/head
ShahanaFarooqui 2 years ago
parent 149561dedb
commit e7b03f4b2f

@ -44,9 +44,6 @@ export const getUTXOs = (req, res, next) => {
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listFunds'; options.url = req.session.selectedNode.ln_server_url + '/v1/listFunds';
request(options).then((body) => { request(options).then((body) => {
if (body.outputs) {
body.outputs = common.sortDescByStrKey(body.outputs, 'status');
}
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body });
res.status(200).json(body); res.status(200).json(body);
}).catch((errRes) => { }).catch((errRes) => {

@ -57,16 +57,16 @@ export var TableSettingsFieldsEnum;
TableSettingsFieldsEnum["RECORDS_PER_PAGE"] = "recordsPerPage"; TableSettingsFieldsEnum["RECORDS_PER_PAGE"] = "recordsPerPage";
TableSettingsFieldsEnum["SORT_BY"] = "sortBy"; TableSettingsFieldsEnum["SORT_BY"] = "sortBy";
TableSettingsFieldsEnum["SORT_ORDER"] = "sortOrder"; TableSettingsFieldsEnum["SORT_ORDER"] = "sortOrder";
TableSettingsFieldsEnum["SHOW_COLUMNS"] = "showColumns"; TableSettingsFieldsEnum["COLUMN_SELECTION"] = "columnSelection";
TableSettingsFieldsEnum["SHOW_COLUMNS_SM"] = "showColumnsSM"; TableSettingsFieldsEnum["COLUMN_SELECTION_SM"] = "columnSelectionSM";
})(TableSettingsFieldsEnum || (TableSettingsFieldsEnum = {})); })(TableSettingsFieldsEnum || (TableSettingsFieldsEnum = {}));
export class TableSetting { export class TableSetting {
constructor(tableId, recordsPerPage, sortBy, sortOrder, showColumns) { constructor(tableId, recordsPerPage, sortBy, sortOrder, columnSelection) {
this.tableId = tableId; this.tableId = tableId;
this.recordsPerPage = recordsPerPage; this.recordsPerPage = recordsPerPage;
this.sortBy = sortBy; this.sortBy = sortBy;
this.sortOrder = sortOrder; this.sortOrder = sortOrder;
this.showColumns = showColumns; this.columnSelection = columnSelection;
} }
} }
export class PageSettings { export class PageSettings {
@ -97,20 +97,20 @@ export const validatePageSettings = (documentToValidate) => {
if (!table.hasOwnProperty(CollectionFieldsEnum.RECORDS_PER_PAGE)) { if (!table.hasOwnProperty(CollectionFieldsEnum.RECORDS_PER_PAGE)) {
errMsg = errMsg + 'Records/Page is mandatory.'; errMsg = errMsg + 'Records/Page is mandatory.';
} }
if (!table.hasOwnProperty(CollectionFieldsEnum.SHOW_COLUMNS_SM)) { if (!table.hasOwnProperty(CollectionFieldsEnum.COLUMN_SELECTION_SM)) {
errMsg = errMsg + 'Show Columns Small Screen is mandatory.'; errMsg = errMsg + 'Column Selection (Mobile) is mandatory.';
} }
if (table[CollectionFieldsEnum.SHOW_COLUMNS_SM].length < 1) { if (table[CollectionFieldsEnum.COLUMN_SELECTION_SM].length < 1) {
errMsg = errMsg + 'Show Columns Small Screen should have at least 1 field.'; errMsg = errMsg + 'Column Selection (Mobile) should have at least 1 field.';
} }
if (table[CollectionFieldsEnum.SHOW_COLUMNS_SM].length > 2) { if (table[CollectionFieldsEnum.COLUMN_SELECTION_SM].length > 2) {
errMsg = errMsg + 'Show Columns Small Screen should have maximum 2 fields.'; errMsg = errMsg + 'Column Selection (Mobile) should have maximum 2 fields.';
} }
if (!table.hasOwnProperty(CollectionFieldsEnum.SHOW_COLUMNS)) { if (!table.hasOwnProperty(CollectionFieldsEnum.COLUMN_SELECTION)) {
errMsg = errMsg + 'Show Columns is mandatory.'; errMsg = errMsg + 'Column Selection (Desktop) is mandatory.';
} }
if (table[CollectionFieldsEnum.SHOW_COLUMNS].length < 2) { if (table[CollectionFieldsEnum.COLUMN_SELECTION].length < 2) {
errMsg = errMsg + 'Show Columns should have at least 2 fields.'; errMsg = errMsg + 'Column Selection (Desktop) should have at least 2 fields.';
} }
if (errMsg.trim() !== '') { if (errMsg.trim() !== '') {
tableAcc.push({ table: (table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID) ? table[CollectionFieldsEnum.TABLE_ID] : (tableIdx + 1)), message: errMsg }); tableAcc.push({ table: (table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID) ? table[CollectionFieldsEnum.TABLE_ID] : (tableIdx + 1)), message: errMsg });

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -10,9 +10,9 @@
<link i18n-rel="" rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5"> <link i18n-rel="" rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5">
<meta i18n-content="" name="msapplication-TileColor" content="#da532c"> <meta i18n-content="" name="msapplication-TileColor" content="#da532c">
<meta i18n-content="" name="theme-color" content="#ffffff"> <meta i18n-content="" name="theme-color" content="#ffffff">
<style>@font-face{font-family:Roboto;src:url(Roboto-Thin.f7a95c9c5999532c.woff2) format("woff2"),url(Roboto-Thin.c13c157cb81e8ebb.woff) format("woff");font-weight:100;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.b0e084abf689f393.woff2) format("woff2"),url(Roboto-ThinItalic.1111028df6cea564.woff) format("woff");font-weight:100;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Light.0e01b6cd13b3857f.woff2) format("woff2"),url(Roboto-Light.603ca9a537b88428.woff) format("woff");font-weight:300;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.232ef4b20215f720.woff2) format("woff2"),url(Roboto-LightItalic.1b5e142f787151c8.woff) format("woff");font-weight:300;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Regular.475ba9e4e2d63456.woff2) format("woff2"),url(Roboto-Regular.bcefbfee882bc1cb.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.e3a9ebdaac06bbc4.woff2) format("woff2"),url(Roboto-RegularItalic.0668fae6af0cf8c2.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Medium.457532032ceb0168.woff2) format("woff2"),url(Roboto-Medium.6e1ae5f0b324a0aa.woff) format("woff");font-weight:500;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.872f7060602d55d2.woff2) format("woff2"),url(Roboto-MediumItalic.e06fb533801cbb08.woff) format("woff");font-weight:500;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Bold.447291a88c067396.woff2) format("woff2"),url(Roboto-Bold.fc482e6133cf5e26.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.1b15168ef6fa4e16.woff2) format("woff2"),url(Roboto-BoldItalic.e26ba339b06f09f7.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Black.2eaa390d458c877d.woff2) format("woff2"),url(Roboto-Black.b25f67ad8583da68.woff) format("woff");font-weight:900;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.7dc03ee444552bc5.woff2) format("woff2"),url(Roboto-BlackItalic.c8dc642467cb3099.woff) format("woff");font-weight:900;font-style:italic}html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:62.5%}body{box-sizing:border-box;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}</style><link rel="stylesheet" href="styles.43515fc39338348b.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.43515fc39338348b.css"></noscript></head> <style>@font-face{font-family:Roboto;src:url(Roboto-Thin.f7a95c9c5999532c.woff2) format("woff2"),url(Roboto-Thin.c13c157cb81e8ebb.woff) format("woff");font-weight:100;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.b0e084abf689f393.woff2) format("woff2"),url(Roboto-ThinItalic.1111028df6cea564.woff) format("woff");font-weight:100;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Light.0e01b6cd13b3857f.woff2) format("woff2"),url(Roboto-Light.603ca9a537b88428.woff) format("woff");font-weight:300;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.232ef4b20215f720.woff2) format("woff2"),url(Roboto-LightItalic.1b5e142f787151c8.woff) format("woff");font-weight:300;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Regular.475ba9e4e2d63456.woff2) format("woff2"),url(Roboto-Regular.bcefbfee882bc1cb.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.e3a9ebdaac06bbc4.woff2) format("woff2"),url(Roboto-RegularItalic.0668fae6af0cf8c2.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Medium.457532032ceb0168.woff2) format("woff2"),url(Roboto-Medium.6e1ae5f0b324a0aa.woff) format("woff");font-weight:500;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.872f7060602d55d2.woff2) format("woff2"),url(Roboto-MediumItalic.e06fb533801cbb08.woff) format("woff");font-weight:500;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Bold.447291a88c067396.woff2) format("woff2"),url(Roboto-Bold.fc482e6133cf5e26.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.1b15168ef6fa4e16.woff2) format("woff2"),url(Roboto-BoldItalic.e26ba339b06f09f7.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Black.2eaa390d458c877d.woff2) format("woff2"),url(Roboto-Black.b25f67ad8583da68.woff) format("woff");font-weight:900;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.7dc03ee444552bc5.woff2) format("woff2"),url(Roboto-BlackItalic.c8dc642467cb3099.woff) format("woff");font-weight:900;font-style:italic}html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:62.5%}body{box-sizing:border-box;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}</style><link rel="stylesheet" href="styles.f23210babf4d5c40.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.f23210babf4d5c40.css"></noscript></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.3a8ac8969006b863.js" type="module"></script><script src="polyfills.eddc63f1737a019a.js" type="module"></script><script src="main.0a28b146399d54a7.js" type="module"></script> <script src="runtime.503f37ba549530ee.js" type="module"></script><script src="polyfills.eddc63f1737a019a.js" type="module"></script><script src="main.3d7b99d9830668b7.js" type="module"></script>
</body></html> </body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(()=>{"use strict";var e,v={},g={};function r(e){var n=g[e];if(void 0!==n)return n.exports;var t=g[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(n,t,f,d)=>{if(!t){var a=1/0;for(i=0;i<e.length;i++){for(var[t,f,d]=e[i],s=!0,o=0;o<t.length;o++)(!1&d||a>=d)&&Object.keys(r.O).every(b=>r.O[b](t[o]))?t.splice(o--,1):(s=!1,d<a&&(a=d));if(s){e.splice(i--,1);var l=f();void 0!==l&&(n=l)}}return n}d=d||0;for(var i=e.length;i>0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[t,f,d]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>e+"."+{564:"f639cfe4254bb226",636:"167692d028bb7a59",893:"9a615c46b89a5a79",924:"244f3c9394b6cf6d"}[e]+".js",r.miniCssF=e=>{},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="RTLApp:";r.l=(t,f,d,i)=>{if(e[t])e[t].push(f);else{var a,s;if(void 0!==d)for(var o=document.getElementsByTagName("script"),l=0;l<o.length;l++){var u=o[l];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==n+d){a=u;break}}a||(s=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",n+d),a.src=r.tu(t)),e[t]=[f];var c=(m,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(_=>_(b)),m)return m(b)},p=setTimeout(c.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=c.bind(null,a.onerror),a.onload=c.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:n=>n},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(f,d)=>{var i=r.o(e,f)?e[f]:void 0;if(0!==i)if(i)d.push(i[2]);else if(666!=f){var a=new Promise((u,c)=>i=e[f]=[u,c]);d.push(i[2]=a);var s=r.p+r.u(f),o=new Error;r.l(s,u=>{if(r.o(e,f)&&(0!==(i=e[f])&&(e[f]=void 0),i)){var c=u&&("load"===u.type?"missing":u.type),p=u&&u.target&&u.target.src;o.message="Loading chunk "+f+" failed.\n("+c+": "+p+")",o.name="ChunkLoadError",o.type=c,o.request=p,i[1](o)}},"chunk-"+f,f)}else e[f]=0},r.O.j=f=>0===e[f];var n=(f,d)=>{var o,l,[i,a,s]=d,u=0;if(i.some(p=>0!==e[p])){for(o in a)r.o(a,o)&&(r.m[o]=a[o]);if(s)var c=s(r)}for(f&&f(d);u<i.length;u++)r.o(e,l=i[u])&&e[l]&&e[l][0](),e[l]=0;return r.O(c)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})(); (()=>{"use strict";var e,v={},g={};function r(e){var n=g[e];if(void 0!==n)return n.exports;var t=g[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(n,t,f,d)=>{if(!t){var a=1/0;for(i=0;i<e.length;i++){for(var[t,f,d]=e[i],s=!0,o=0;o<t.length;o++)(!1&d||a>=d)&&Object.keys(r.O).every(b=>r.O[b](t[o]))?t.splice(o--,1):(s=!1,d<a&&(a=d));if(s){e.splice(i--,1);var l=f();void 0!==l&&(n=l)}}return n}d=d||0;for(var i=e.length;i>0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[t,f,d]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>e+"."+{258:"ef54ce47dace49e4",267:"6fb96d7d2bc58b98",564:"ff48c37cffd166ba",636:"c0cbf4123331dffc"}[e]+".js",r.miniCssF=e=>{},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="RTLApp:";r.l=(t,f,d,i)=>{if(e[t])e[t].push(f);else{var a,s;if(void 0!==d)for(var o=document.getElementsByTagName("script"),l=0;l<o.length;l++){var u=o[l];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==n+d){a=u;break}}a||(s=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",n+d),a.src=r.tu(t)),e[t]=[f];var c=(m,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(_=>_(b)),m)return m(b)},p=setTimeout(c.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=c.bind(null,a.onerror),a.onload=c.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:n=>n},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(f,d)=>{var i=r.o(e,f)?e[f]:void 0;if(0!==i)if(i)d.push(i[2]);else if(666!=f){var a=new Promise((u,c)=>i=e[f]=[u,c]);d.push(i[2]=a);var s=r.p+r.u(f),o=new Error;r.l(s,u=>{if(r.o(e,f)&&(0!==(i=e[f])&&(e[f]=void 0),i)){var c=u&&("load"===u.type?"missing":u.type),p=u&&u.target&&u.target.src;o.message="Loading chunk "+f+" failed.\n("+c+": "+p+")",o.name="ChunkLoadError",o.type=c,o.request=p,i[1](o)}},"chunk-"+f,f)}else e[f]=0},r.O.j=f=>0===e[f];var n=(f,d)=>{var o,l,[i,a,s]=d,u=0;if(i.some(p=>0!==e[p])){for(o in a)r.o(a,o)&&(r.m[o]=a[o]);if(s)var c=s(r)}for(f&&f(d);u<i.length;u++)r.o(e,l=i[u])&&e[l]&&e[l][0](),e[l]=0;return r.O(c)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -41,7 +41,6 @@ export const getUTXOs = (req, res, next) => {
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listFunds'; options.url = req.session.selectedNode.ln_server_url + '/v1/listFunds';
request(options).then((body) => { request(options).then((body) => {
if (body.outputs) { body.outputs = common.sortDescByStrKey(body.outputs, 'status'); }
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body });
res.status(200).json(body); res.status(200).json(body);
}).catch((errRes) => { }).catch((errRes) => {

@ -61,8 +61,8 @@ export enum TableSettingsFieldsEnum {
RECORDS_PER_PAGE = 'recordsPerPage', RECORDS_PER_PAGE = 'recordsPerPage',
SORT_BY = 'sortBy', SORT_BY = 'sortBy',
SORT_ORDER = 'sortOrder', SORT_ORDER = 'sortOrder',
SHOW_COLUMNS = 'showColumns', COLUMN_SELECTION = 'columnSelection',
SHOW_COLUMNS_SM = 'showColumnsSM' COLUMN_SELECTION_SM = 'columnSelectionSM'
} }
export class TableSetting { export class TableSetting {
@ -72,7 +72,7 @@ export class TableSetting {
public recordsPerPage?: number, public recordsPerPage?: number,
public sortBy?: string, public sortBy?: string,
public sortOrder?: SortOrderEnum, public sortOrder?: SortOrderEnum,
public showColumns?: any[] public columnSelection?: any[]
) { } ) { }
} }
@ -108,20 +108,20 @@ export const validatePageSettings = (documentToValidate): any => {
if (!table.hasOwnProperty(CollectionFieldsEnum.RECORDS_PER_PAGE)) { if (!table.hasOwnProperty(CollectionFieldsEnum.RECORDS_PER_PAGE)) {
errMsg = errMsg + 'Records/Page is mandatory.'; errMsg = errMsg + 'Records/Page is mandatory.';
} }
if (!table.hasOwnProperty(CollectionFieldsEnum.SHOW_COLUMNS_SM)) { if (!table.hasOwnProperty(CollectionFieldsEnum.COLUMN_SELECTION_SM)) {
errMsg = errMsg + 'Show Columns Small Screen is mandatory.'; errMsg = errMsg + 'Column Selection (Mobile) is mandatory.';
} }
if (table[CollectionFieldsEnum.SHOW_COLUMNS_SM].length < 1) { if (table[CollectionFieldsEnum.COLUMN_SELECTION_SM].length < 1) {
errMsg = errMsg + 'Show Columns Small Screen should have at least 1 field.'; errMsg = errMsg + 'Column Selection (Mobile) should have at least 1 field.';
} }
if (table[CollectionFieldsEnum.SHOW_COLUMNS_SM].length > 2) { if (table[CollectionFieldsEnum.COLUMN_SELECTION_SM].length > 2) {
errMsg = errMsg + 'Show Columns Small Screen should have maximum 2 fields.'; errMsg = errMsg + 'Column Selection (Mobile) should have maximum 2 fields.';
} }
if (!table.hasOwnProperty(CollectionFieldsEnum.SHOW_COLUMNS)) { if (!table.hasOwnProperty(CollectionFieldsEnum.COLUMN_SELECTION)) {
errMsg = errMsg + 'Show Columns is mandatory.'; errMsg = errMsg + 'Column Selection (Desktop) is mandatory.';
} }
if (table[CollectionFieldsEnum.SHOW_COLUMNS].length < 2) { if (table[CollectionFieldsEnum.COLUMN_SELECTION].length < 2) {
errMsg = errMsg + 'Show Columns should have at least 2 fields.'; errMsg = errMsg + 'Column Selection (Desktop) should have at least 2 fields.';
} }
if (errMsg.trim() !== '') { if (errMsg.trim() !== '') {
tableAcc.push({ table: (table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID) ? table[CollectionFieldsEnum.TABLE_ID] : (tableIdx + 1)), message: errMsg }); tableAcc.push({ table: (table.hasOwnProperty(CollectionFieldsEnum.TABLE_ID) ? table[CollectionFieldsEnum.TABLE_ID] : (tableIdx + 1)), message: errMsg });

@ -4,13 +4,13 @@
<ng-template mat-tab-label> <ng-template mat-tab-label>
<span matBadge="{{numUtxos}}" matBadgeOverlap="false" class="tab-badge">UTXOs</span> <span matBadge="{{numUtxos}}" matBadgeOverlap="false" class="tab-badge">UTXOs</span>
</ng-template> </ng-template>
<rtl-cln-on-chain-utxos [utxos]="utxos" [numDustUTXOs]="numDustUtxos" [isDustUTXO]="false" xLayout="row" fxFlex="100"></rtl-cln-on-chain-utxos> <rtl-cln-on-chain-utxos [numDustUTXOs]="numDustUtxos" [isDustUTXO]="false" xLayout="row" fxFlex="100"></rtl-cln-on-chain-utxos>
</mat-tab> </mat-tab>
<mat-tab> <mat-tab>
<ng-template mat-tab-label> <ng-template mat-tab-label>
<span matBadge="{{numDustUtxos}}" matBadgeOverlap="false" class="tab-badge">Dust UTXOs</span> <span matBadge="{{numDustUtxos}}" matBadgeOverlap="false" class="tab-badge">Dust UTXOs</span>
</ng-template> </ng-template>
<rtl-cln-on-chain-utxos [utxos]="dustUtxos" [numDustUTXOs]="numDustUtxos" [isDustUTXO]="true" fxLayout="row" fxFlex="100"></rtl-cln-on-chain-utxos> <rtl-cln-on-chain-utxos [numDustUTXOs]="numDustUtxos" [isDustUTXO]="true" fxLayout="row" fxFlex="100"></rtl-cln-on-chain-utxos>
</mat-tab> </mat-tab>
</mat-tab-group> </mat-tab-group>
</div> </div>

@ -1,5 +1,6 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { StoreModule } from '@ngrx/store'; import { StoreModule } from '@ngrx/store';
import { CommonService } from '../../../shared/services/common.service'; import { CommonService } from '../../../shared/services/common.service';
import { DataService } from '../../../shared/services/data.service'; import { DataService } from '../../../shared/services/data.service';
@ -24,6 +25,7 @@ describe('CLNUTXOTablesComponent', () => {
imports: [ imports: [
BrowserAnimationsModule, BrowserAnimationsModule,
SharedModule, SharedModule,
RouterTestingModule,
StoreModule.forRoot({ root: RootReducer, lnd: LNDReducer, cln: CLNReducer, ecl: ECLReducer }) StoreModule.forRoot({ root: RootReducer, lnd: LNDReducer, cln: CLNReducer, ecl: ECLReducer })
], ],
providers: [ providers: [

@ -19,9 +19,7 @@ export class CLNUTXOTablesComponent implements OnInit, OnDestroy {
@Input() selectedTableIndex = 0; @Input() selectedTableIndex = 0;
@Output() readonly selectedTableIndexChange = new EventEmitter<number>(); @Output() readonly selectedTableIndexChange = new EventEmitter<number>();
public utxos: UTXO[] = [];
public numUtxos = 0; public numUtxos = 0;
public dustUtxos: UTXO[] = [];
public numDustUtxos = 0; public numDustUtxos = 0;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()]; private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
@ -31,14 +29,8 @@ export class CLNUTXOTablesComponent implements OnInit, OnDestroy {
this.store.select(utxos).pipe(takeUntil(this.unSubs[0])). this.store.select(utxos).pipe(takeUntil(this.unSubs[0])).
subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => { subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => {
if (utxosSeletor.utxos && utxosSeletor.utxos.length > 0) { if (utxosSeletor.utxos && utxosSeletor.utxos.length > 0) {
this.utxos = utxosSeletor.utxos; this.numUtxos = utxosSeletor.utxos.length || 0;
this.numUtxos = this.utxos.length; this.numDustUtxos = utxosSeletor.utxos?.filter((utxo) => +(utxo.value || 0) < 1000).length || 0;
this.dustUtxos = utxosSeletor.utxos?.filter((utxo) => +(utxo.value || 0) < 1000);
this.numDustUtxos = this.dustUtxos.length;
}
if (utxosSeletor.utxos && utxosSeletor.utxos.length > 0) {
this.utxos = utxosSeletor.utxos;
this.numUtxos = this.utxos.length;
} }
this.logger.info(utxosSeletor); this.logger.info(utxosSeletor);
}); });

@ -1,7 +1,7 @@
<div fxLayout="row wrap" fxLayoutAlign="start start" fxLayout.gt-sm="column" fxFlex="100" fxLayoutAlign.gt-sm="start stretch" class="padding-gap-x-large"> <div fxLayout="column" fxLayoutAlign="start stretch" fxFlex="100" class="padding-gap-x-large">
<div fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="page-sub-title-container"> <div fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start stretch" class="page-sub-title-container">
<div fxFlex="70"></div> <div fxFlex="70" fxLayoutAlign="start start" fxLayoutAlign.gt-sm="start center"></div>
<mat-form-field fxFlex="30"> <mat-form-field fxFlex="30" fxLayoutAlign="start end">
<input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter"> <input matInput (keyup)="applyFilter()" [(ngModel)]="selFilter" placeholder="Filter">
</mat-form-field> </mat-form-field>
</div> </div>
@ -9,21 +9,44 @@
<div [perfectScrollbar] class="table-container" fxFlex="100"> <div [perfectScrollbar] class="table-container" fxFlex="100">
<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 [dataSource]="listUTXOs" matSort [ngClass]="{'overflow-auto error-border': errorMessage !== '','overflow-auto': true}"> <table mat-table #table [dataSource]="listUTXOs" matSort [ngClass]="{'overflow-auto error-border': errorMessage !== '','overflow-auto': true}">
<ng-container matColumnDef="txid"> <ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Transaction ID </th> <th mat-header-cell *matHeaderCellDef mat-sort-header>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>
<td mat-cell *matCellDef="let utxo"> <td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '50rem'}"> <span fxLayout="row" fxLayoutAlign="end center" >
<span *ngIf="numDustUTXOs > 0 && !isDustUTXO"> <span *ngIf="numDustUTXOs > 0 && !isDustUTXO">
<span *ngIf="utxo.value < 1000; else emptySpace" matTooltip="Risk of dust attack" matTooltipPosition="right"> <span *ngIf="utxo.value < 1000; else emptySpace" matTooltip="Risk of dust attack" matTooltipPosition="right">
<mat-icon fxLayoutAlign="start center" color="warn" class="mr-1">warning</mat-icon> <mat-icon fxLayoutAlign="start start" color="warn" class="mr-1">warning</mat-icon>
</span> </span>
</span> </span>
<span *ngIf="utxo.status === 'confirmed'" class="dot green" matTooltip="Confirmed" matTooltipPosition="right"></span> <span *ngIf="utxo.status === 'confirmed'" class="dot green" matTooltip="Confirmed" matTooltipPosition="right"></span>
<span *ngIf="utxo.status !== 'confirmed'" class="dot yellow" matTooltip="{{utxo.status | titlecase}}" matTooltipPosition="right"></span> <span *ngIf="utxo.status !== 'confirmed'" class="dot yellow" matTooltip="{{utxo.status | titlecase}}" matTooltipPosition="right"></span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="txid">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Transaction ID </th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">
<span class="ellipsis-child">{{utxo.txid}}</span> <span class="ellipsis-child">{{utxo.txid}}</span>
</span> </span>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="address">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Address </th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">
<span class="ellipsis-child">{{utxo.address}}</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="scriptpubkey">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Script Pubkey </th>
<td mat-cell *matCellDef="let utxo">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">
<span class="ellipsis-child">{{utxo.scriptpubkey}}</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="output"> <ng-container matColumnDef="output">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Output </th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Output </th>
<td mat-cell *matCellDef="let utxo"><span fxLayoutAlign="end center"> <td mat-cell *matCellDef="let utxo"><span fxLayoutAlign="end center">
@ -41,8 +64,14 @@
<td mat-cell *matCellDef="let utxo"><span fxLayoutAlign="end center"> <td mat-cell *matCellDef="let utxo"><span fxLayoutAlign="end center">
{{utxo?.blockheight | number}} </span></td> {{utxo?.blockheight | number}} </span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="reserved">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="pl-3"> Reserved </th>
<td mat-cell *matCellDef="let utxo" class="pl-3">
<span>{{utxo.reserved ? 'Yes' : 'No'}}</span>
</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>
@ -50,7 +79,7 @@
</mat-select> </mat-select>
</div> </div>
</th> </th>
<td mat-cell *matCellDef="let utxo" class="pl-3" fxLayoutAlign="end center"> <td mat-cell *matCellDef="let utxo" fxLayoutAlign="end center">
<button mat-stroked-button color="primary" type="button" tabindex="4" (click)="onUTXOClick(utxo, $event)">View Info</button> <button mat-stroked-button color="primary" type="button" tabindex="4" (click)="onUTXOClick(utxo, $event)">View Info</button>
</td> </td>
</ng-container> </ng-container>

@ -1,4 +1,10 @@
.mat-column-txid { @import '../../../../shared/theme/styles/mixins.scss';
.mat-column-status {
width: 6rem;
}
.mat-column-txid, .mat-column-address, .mat-column-scriptpubkey {
flex: 0 0 15%; flex: 0 0 15%;
width: 15%; width: 15%;
& .ellipsis-parent { & .ellipsis-parent {

@ -1,5 +1,6 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { StoreModule } from '@ngrx/store'; import { StoreModule } from '@ngrx/store';
import { CommonService } from '../../../../shared/services/common.service'; import { CommonService } from '../../../../shared/services/common.service';
import { DataService } from '../../../../shared/services/data.service'; import { DataService } from '../../../../shared/services/data.service';
@ -23,6 +24,7 @@ describe('CLNOnChainUtxosComponent', () => {
imports: [ imports: [
BrowserAnimationsModule, BrowserAnimationsModule,
SharedModule, SharedModule,
RouterTestingModule,
StoreModule.forRoot({ root: RootReducer, lnd: LNDReducer, cln: CLNReducer, ecl: ECLReducer }) StoreModule.forRoot({ root: RootReducer, lnd: LNDReducer, cln: CLNReducer, ecl: ECLReducer })
], ],
providers: [ providers: [

@ -1,4 +1,5 @@
import { Component, ViewChild, Input, OnChanges, AfterViewInit, OnDestroy, OnInit } from '@angular/core'; import { Component, ViewChild, Input, AfterViewInit, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@ -7,14 +8,15 @@ 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 { UTXO } from '../../../../shared/models/clnModels'; import { UTXO } from '../../../../shared/models/clnModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum } from '../../../../shared/services/consts-enums-functions'; import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, CLN_DEFAULT_PAGE_SETTINGS } from '../../../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload'; import { ApiCallStatusPayload } from '../../../../shared/models/apiCallsPayload';
import { LoggerService } from '../../../../shared/services/logger.service'; import { LoggerService } from '../../../../shared/services/logger.service';
import { CommonService } from '../../../../shared/services/common.service'; import { CommonService } from '../../../../shared/services/common.service';
import { RTLState } from '../../../../store/rtl.state'; import { RTLState } from '../../../../store/rtl.state';
import { openAlert } from '../../../../store/rtl.actions'; import { openAlert } from '../../../../store/rtl.actions';
import { utxos } from '../../../store/cln.selector'; import { clnPageSettings, utxos } from '../../../store/cln.selector';
import { PageSettingsCLN, TableSetting } from '../../../../shared/models/pageSettings';
@Component({ @Component({
selector: 'rtl-cln-on-chain-utxos', selector: 'rtl-cln-on-chain-utxos',
@ -24,14 +26,16 @@ import { utxos } from '../../../store/cln.selector';
{ provide: MatPaginatorIntl, useValue: getPaginatorLabel('UTXOs') } { provide: MatPaginatorIntl, useValue: getPaginatorLabel('UTXOs') }
] ]
}) })
export class CLNOnChainUtxosComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy { export class CLNOnChainUtxosComponent 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;
@Input() numDustUTXOs = 0; @Input() numDustUTXOs = 0;
@Input() isDustUTXO = false; @Input() isDustUTXO = false;
@Input() utxos: UTXO[]; public PAGE_ID = 'on-chain';
public tableSetting: TableSetting = { tableId: 'utxos', recordsPerPage: 10, sortBy: 'status', sortOrder: SortOrderEnum.DESCENDING };
public displayedColumns: any[] = []; public displayedColumns: any[] = [];
public utxos: UTXO[];
public listUTXOs: any; public listUTXOs: any;
public pageSize = PAGE_SIZE; public pageSize = PAGE_SIZE;
public pageSizeOptions = PAGE_SIZE_OPTIONS; public pageSizeOptions = PAGE_SIZE_OPTIONS;
@ -41,29 +45,45 @@ export class CLNOnChainUtxosComponent implements OnInit, OnChanges, AfterViewIni
public selFilter = ''; public selFilter = '';
public apiCallStatus: ApiCallStatusPayload | null = null; public apiCallStatus: ApiCallStatusPayload | null = null;
public apiCallStatusEnum = APICallStatusEnum; public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()]; private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>) { constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private router: Router) {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if (this.screenSize === ScreenSizeEnum.XS) {
this.displayedColumns = ['txid', 'value', 'actions'];
} else if (this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = ['txid', 'output', 'value', 'blockheight', 'actions'];
} else if (this.screenSize === ScreenSizeEnum.MD) {
this.displayedColumns = ['txid', 'output', 'value', 'blockheight', 'actions'];
} else {
this.displayedColumns = ['txid', 'output', 'value', 'blockheight', 'actions'];
}
} }
ngOnInit() { ngOnInit() {
this.store.select(utxos).pipe(takeUntil(this.unSubs[0])). this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.tableSetting.tableId = this.isDustUTXO ? 'dust_utxos' : 'utxos';
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.unshift('status');
this.displayedColumns.push('actions');
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.logger.info(this.displayedColumns);
});
this.store.select(utxos).pipe(takeUntil(this.unSubs[1])).
subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => { subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => {
this.errorMessage = ''; this.errorMessage = '';
this.apiCallStatus = utxosSeletor.apiCallStatus; this.apiCallStatus = utxosSeletor.apiCallStatus;
if (this.apiCallStatus.status === APICallStatusEnum.ERROR) { if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {
this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message; this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;
} }
this.utxos = (this.isDustUTXO) ? utxosSeletor.utxos?.filter((utxo) => +(utxo.value || 0) < 1000) : utxosSeletor.utxos ? utxosSeletor.utxos : [];
if (this.utxos && this.utxos.length > 0 && this.sort && this.paginator) {
this.loadUTXOsTable(this.utxos);
}
this.logger.info(utxosSeletor); this.logger.info(utxosSeletor);
}); });
} }
@ -74,12 +94,6 @@ export class CLNOnChainUtxosComponent implements OnInit, OnChanges, AfterViewIni
} }
} }
ngOnChanges() {
if (this.utxos && this.utxos.length > 0) {
this.loadUTXOsTable(this.utxos);
}
}
applyFilter() { applyFilter() {
this.listUTXOs.filter = this.selFilter.trim().toLowerCase(); this.listUTXOs.filter = this.selFilter.trim().toLowerCase();
} }
@ -108,6 +122,7 @@ export class CLNOnChainUtxosComponent implements OnInit, OnChanges, AfterViewIni
this.listUTXOs = new MatTableDataSource<UTXO>([...utxos]); this.listUTXOs = new MatTableDataSource<UTXO>([...utxos]);
this.listUTXOs.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null); this.listUTXOs.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.listUTXOs.sort = this.sort; this.listUTXOs.sort = this.sort;
this.listUTXOs.sort.sort({ id: this.tableSetting.sortBy, start: this.tableSetting.sortOrder, disableClear: true });
this.listUTXOs.filterPredicate = (utxo: UTXO, fltr: string) => JSON.stringify(utxo).toLowerCase().includes(fltr); this.listUTXOs.filterPredicate = (utxo: UTXO, fltr: string) => JSON.stringify(utxo).toLowerCase().includes(fltr);
this.listUTXOs.paginator = this.paginator; this.listUTXOs.paginator = this.paginator;
this.applyFilter(); this.applyFilter();

@ -1,23 +1,7 @@
@import '../../../../shared/theme/styles/mixins.scss'; @import '../../../../shared/theme/styles/mixins.scss';
.mat-column-status { .mat-column-status {
max-width: 1rem; width: 2rem;
& .dot {
@include for_screensize(tab-port) {
width:0.6rem;
height: 0.6rem;
left: 2.8rem;
margin-top: -0.3rem;
position: absolute;
}
@include for_screensize(phone) {
width:0.6rem;
height: 0.6rem;
left: 0.8rem;
margin-top: -0.3rem;
position: absolute;
}
}
} }
.mat-column-description, .mat-column-label, .mat-column-payment_hash, .mat-column-bolt11 { .mat-column-description, .mat-column-label, .mat-column-payment_hash, .mat-column-bolt11 {

@ -64,7 +64,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
public selFilter = ''; public selFilter = '';
public apiCallStatus: ApiCallStatusPayload | null = null; public apiCallStatus: ApiCallStatusPayload | null = null;
public apiCallStatusEnum = APICallStatusEnum; public apiCallStatusEnum = APICallStatusEnum;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private rtlEffects: RTLEffects, private datePipe: DatePipe, private actions: Actions) { constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private rtlEffects: RTLEffects, private datePipe: DatePipe, private actions: Actions) {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
@ -86,16 +86,16 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
} }
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)!; 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) { if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.showColumnsSM)); this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));
} else { } else {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.showColumns)); this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));
} }
this.displayedColumns.unshift('status'); this.displayedColumns.unshift('status');
this.displayedColumns.push('actions'); this.displayedColumns.push('actions');
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE; this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.logger.info(this.displayedColumns); this.logger.info(this.displayedColumns);
}); });
this.store.select(listInvoices).pipe(takeUntil(this.unSubs[2])). this.store.select(listInvoices).pipe(takeUntil(this.unSubs[3])).
subscribe((invoicesSeletor: { listInvoices: ListInvoices, apiCallStatus: ApiCallStatusPayload }) => { subscribe((invoicesSeletor: { listInvoices: ListInvoices, apiCallStatus: ApiCallStatusPayload }) => {
this.errorMessage = ''; this.errorMessage = '';
this.apiCallStatus = invoicesSeletor.apiCallStatus; this.apiCallStatus = invoicesSeletor.apiCallStatus;
@ -108,7 +108,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
} }
this.logger.info(invoicesSeletor); this.logger.info(invoicesSeletor);
}); });
this.actions.pipe(takeUntil(this.unSubs[3]), filter((action) => (action.type === CLNActions.SET_LOOKUP_CLN || action.type === CLNActions.UPDATE_API_CALL_STATUS_CLN))). this.actions.pipe(takeUntil(this.unSubs[4]), filter((action) => (action.type === CLNActions.SET_LOOKUP_CLN || action.type === CLNActions.UPDATE_API_CALL_STATUS_CLN))).
subscribe((resLookup: any) => { subscribe((resLookup: any) => {
if (resLookup.type === CLNActions.SET_LOOKUP_CLN) { if (resLookup.type === CLNActions.SET_LOOKUP_CLN) {
if (this.invoiceJSONArr && this.invoiceJSONArr.length > 0 && this.sort && this.paginator && resLookup.payload) { if (this.invoiceJSONArr && this.invoiceJSONArr.length > 0 && this.sort && this.paginator && resLookup.payload) {
@ -158,7 +158,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
} }
})); }));
this.rtlEffects.closeConfirm. this.rtlEffects.closeConfirm.
pipe(takeUntil(this.unSubs[4])). pipe(takeUntil(this.unSubs[5])).
subscribe((confirmRes) => { subscribe((confirmRes) => {
if (confirmRes) { if (confirmRes) {
this.store.dispatch(deleteExpiredInvoice({ payload: null })); this.store.dispatch(deleteExpiredInvoice({ payload: null }));
@ -205,7 +205,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
if (this.selNode && this.selNode.fiatConversion && this.invoiceValue! > 99) { if (this.selNode && this.selNode.fiatConversion && this.invoiceValue! > 99) {
this.invoiceValueHint = ''; this.invoiceValueHint = '';
this.commonService.convertCurrency(this.invoiceValue!, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode?.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion). this.commonService.convertCurrency(this.invoiceValue!, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode?.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).
pipe(takeUntil(this.unSubs[5])). pipe(takeUntil(this.unSubs[6])).
subscribe({ subscribe({
next: (data) => { next: (data) => {
this.invoiceValueHint = '= ' + data.symbol + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit; this.invoiceValueHint = '= ' + data.symbol + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;

@ -1,29 +1,7 @@
@import '../../../shared/theme/styles/mixins.scss'; @import '../../../shared/theme/styles/mixins.scss';
.mat-column-status, .mat-column-group_status { .mat-column-status, .mat-column-group_status {
max-width: 0.2rem; width: 2rem;
@include for_screensize(tab-port) {
min-width: 1rem;
}
@include for_screensize(phone) {
min-width: 1rem;
}
& .dot {
@include for_screensize(tab-port) {
width:0.6rem;
height: 0.6rem;
left: 4rem;
margin-top: -0.4rem;
position: absolute;
}
@include for_screensize(phone) {
width:0.6rem;
height: 0.6rem;
left: 0;
margin-top: -0.2rem;
position: absolute;
}
}
} }
.mat-column-payment_hash, .mat-column-bolt11, .mat-column-destination, .mat-column-label, .mat-column-memo { .mat-column-payment_hash, .mat-column-bolt11, .mat-column-destination, .mat-column-label, .mat-column-memo {

@ -83,9 +83,9 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
} }
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)!; 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) { if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.showColumnsSM)); this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));
} else { } else {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.showColumns)); this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));
} }
this.displayedColumns.unshift('status'); this.displayedColumns.unshift('status');
this.displayedColumns.push('actions'); this.displayedColumns.push('actions');

@ -2,15 +2,16 @@
<form fxLayout="column" fxLayoutAlign="start stretch" class="settings-container page-sub-title-container mt-1" #form="ngForm"> <form fxLayout="column" fxLayoutAlign="start stretch" class="settings-container page-sub-title-container mt-1" #form="ngForm">
<div fxLayout="row"> <div fxLayout="row">
<fa-icon [icon]="faPenRuler" class="page-title-img mr-1"></fa-icon> <fa-icon [icon]="faPenRuler" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Page Settings</span> <span class="page-title">Grid Settings</span>
</div> </div>
<ng-container *ngIf="errorMessage && errorMessage.page === 'unknown'" [ngTemplateOutlet]="errorObjectBlock" [ngTemplateOutletContext]="{error: errorMessage}"></ng-container> <ng-container *ngIf="errorMessage && errorMessage.page === 'unknown'" [ngTemplateOutlet]="errorObjectBlock" [ngTemplateOutletContext]="{error: errorMessage}"></ng-container>
<mat-expansion-panel fxLayout="column" class="flat-expansion-panel mt-1" [ngClass]="{'error-border': errorMessage?.page === page.pageId}" expanded="true" *ngFor="let page of pageSettings"> <mat-expansion-panel fxLayout="column" class="flat-expansion-panel mt-1" [ngClass]="{'error-border': errorMessage?.page === page.pageId}" expanded="true" *ngFor="let page of pageSettings">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title>{{page.pageId | titlecase}}</mat-panel-title> <mat-panel-title>{{page.pageId | titlecase}}</mat-panel-title>
</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"> <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" class="mt-1"> <div fxLayout="row" fxLayoutAlign="space-between center">
<span fxFlex="10">Table {{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="1" required>
<mat-option *ngFor="let pageSizeOption of pageSizeOptions" [value]="pageSizeOption"> <mat-option *ngFor="let pageSizeOption of pageSizeOptions" [value]="pageSizeOption">
@ -20,7 +21,7 @@
</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="2" required>
<mat-option *ngFor="let field of table.showColumns" [value]="field"> <mat-option *ngFor="let field of table.columnSelection" [value]="field">
{{field | camelcaseWithReplace:'_'}} {{field | camelcaseWithReplace:'_'}}
</mat-option> </mat-option>
</mat-select> </mat-select>
@ -32,21 +33,21 @@
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="13"> <mat-form-field fxFlex="18">
<mat-select [(ngModel)]="table.showColumnsSM" placeholder="Small Screen Columns" name="{{table.tableId}}-show-columns-sm" tabindex="4" multiple required> <mat-select [(ngModel)]="table.columnSelectionSM" placeholder="Column selection (Mobile)" name="{{table.tableId}}-columns-selection-sm" tabindex="4" multiple required>
<mat-option *ngFor="let field of table.showColumns" [value]="field" [disabled]="(table.showColumns.length <= 1 && table.showColumns.includes(field)) || (table.showColumns.length >= 2 && !table.showColumns.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>
</mat-select> </mat-select>
<mat-hint>Small screen selected columns 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="55"> <mat-form-field fxFlex="40">
<mat-select [(ngModel)]="table.showColumns" (selectionChange)="onShowColumnsChange(table)" placeholder="Show Columns" name="{{table.tableId}}-show-columns" tabindex="5" multiple required> <mat-select [(ngModel)]="table.columnSelection" (selectionChange)="oncolumnSelectionChange(table)" placeholder="Column selection (Desktop)" name="{{table.tableId}}-columns-selection" tabindex="5" multiple required>
<mat-option *ngFor="let field of tableFieldsDef[table.tableId].allowedColumns" [value]="field" [disabled]="(table.showColumns.length <= 2 && table.showColumns.includes(field)) || (table.showColumns.length >= tableFieldsDef[table.tableId].maxColumns && !table.showColumns.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>Total selected columns 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>
</div> </div>
</div> </div>
@ -54,8 +55,9 @@
</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()" tabindex="6">Reset</button> <button class="mr-1" mat-stroked-button color="primary" (click)="onResetPageSettings('current')" tabindex="6">Reset</button>
<button mat-flat-button color="primary" (click)="onUpdatePageSettings()" tabindex="7">Save</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>
</div> </div>
</div> </div>
<ng-template #errorObjectBlock let-error="error"> <ng-template #errorObjectBlock let-error="error">

@ -0,0 +1,8 @@
.table-setting-row {
&:last-child {
margin-bottom: 3rem;
}
&:not(:first-child) {
margin: 3rem 0;
}
}

@ -1,4 +1,5 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store'; import { StoreModule } from '@ngrx/store';
import { RootReducer } from '../../../../store/rtl.reducers'; import { RootReducer } from '../../../../store/rtl.reducers';
@ -7,9 +8,9 @@ import { CLNReducer } from '../../../../cln/store/cln.reducers';
import { ECLReducer } from '../../../../eclair/store/ecl.reducers'; import { ECLReducer } from '../../../../eclair/store/ecl.reducers';
import { CommonService } from '../../../services/common.service'; import { CommonService } from '../../../services/common.service';
import { LoggerService } from '../../../services/logger.service'; import { LoggerService } from '../../../services/logger.service';
import { mockCLEffects, mockDataService, mockECLEffects, mockLNDEffects, mockLoggerService, mockRTLEffects } from '../../../../shared/test-helpers/mock-services';
import { PageSettingsComponent } from './page-settings.component'; import { PageSettingsComponent } from './page-settings.component';
import { mockDataService, mockLoggerService } from '../../../test-helpers/mock-services';
import { SharedModule } from '../../../shared.module'; import { SharedModule } from '../../../shared.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DataService } from '../../../services/data.service'; import { DataService } from '../../../services/data.service';
@ -24,7 +25,8 @@ describe('PageSettingsComponent', () => {
imports: [ imports: [
BrowserAnimationsModule, BrowserAnimationsModule,
SharedModule, SharedModule,
StoreModule.forRoot({ root: RootReducer, lnd: LNDReducer, cln: CLNReducer, ecl: ECLReducer }) StoreModule.forRoot({ root: RootReducer, lnd: LNDReducer, cln: CLNReducer, ecl: ECLReducer }),
EffectsModule.forRoot([mockRTLEffects, mockLNDEffects, mockCLEffects, mockECLEffects])
], ],
providers: [ providers: [
CommonService, CommonService,

@ -59,23 +59,29 @@ export class PageSettingsComponent implements OnInit, OnDestroy {
}); });
} }
onShowColumnsChange(table: TableSetting) { oncolumnSelectionChange(table: TableSetting) {
if (table.showColumns && !table.showColumns.includes(table.sortBy)) { if (table.columnSelection && !table.columnSelection.includes(table.sortBy)) {
table.sortBy = table.showColumns[0]; table.sortBy = table.columnSelection[0];
} }
} }
onUpdatePageSettings(): boolean | void { onUpdatePageSettings(): boolean | void {
if (this.pageSettings.reduce((pacc, page) => pacc || (page.tables.reduce((acc, table) => !(table.recordsPerPage && table.sortBy && table.sortOrder && table.showColumns && table.showColumns.length >= 2), false)), false)) { if (this.pageSettings.reduce((pacc, page) => pacc || (page.tables.reduce((acc, table) => !(table.recordsPerPage && table.sortBy && table.sortOrder && table.columnSelection && table.columnSelection.length >= 2), false)), false)) {
return true; return true;
} }
this.errorMessage = ''; this.errorMessage = '';
this.store.dispatch(savePageSettings({ payload: this.pageSettings })); this.store.dispatch(savePageSettings({ payload: this.pageSettings }));
} }
onResetPageSettings() { onResetPageSettings(prev: string) {
this.errorMessage = null; if (prev === 'current') {
this.pageSettings = this.initialPageSettings; this.errorMessage = null;
this.pageSettings = this.initialPageSettings;
} else {
this.errorMessage = null;
this.pageSettings = CLN_DEFAULT_PAGE_SETTINGS;
this.onUpdatePageSettings();
}
} }
ngOnDestroy() { ngOnDestroy() {

@ -6,8 +6,8 @@ export class TableSetting {
recordsPerPage?: number; recordsPerPage?: number;
sortBy?: string; sortBy?: string;
sortOrder?: SortOrderEnum; sortOrder?: SortOrderEnum;
showColumnsSM?: any[]; columnSelectionSM?: any[];
showColumns?: any[]; columnSelection?: any[];
} }

@ -675,12 +675,24 @@ 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, { pageId: 'payments', tables: [
showColumnsSM: ['created_at', 'msatoshi'], { tableId: 'payments', recordsPerPage: PAGE_SIZE, sortBy: 'created_at', sortOrder: SortOrderEnum.DESCENDING,
showColumns: ['created_at', 'type', 'payment_hash', 'msatoshi_sent', 'msatoshi'] }] }, columnSelectionSM: ['created_at', 'msatoshi'],
{ pageId: 'invoices', tables: [{ tableId: 'invoices', recordsPerPage: PAGE_SIZE, sortBy: 'expires_at', sortOrder: SortOrderEnum.DESCENDING, columnSelection: ['created_at', 'type', 'payment_hash', 'msatoshi_sent', 'msatoshi'] }
showColumnsSM: ['expires_at', 'msatoshi'], ] },
showColumns: ['expires_at', 'paid_at', 'type', 'description', 'msatoshi', 'msatoshi_received'] }] } { 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'],
columnSelection: ['txid', 'output', 'value', 'blockheight'] },
{ tableId: 'dust_utxos', recordsPerPage: PAGE_SIZE, sortBy: 'blockheight', sortOrder: SortOrderEnum.DESCENDING,
columnSelectionSM: ['txid', 'value'],
columnSelection: ['txid', 'output', 'value', 'blockheight'] }
] }
]; ];
export const CLN_TABLES_DEF = { export const CLN_TABLES_DEF = {
@ -691,5 +703,13 @@ export const CLN_TABLES_DEF = {
invoices: { invoices: {
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: {
maxColumns: 7,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved']
},
dust_utxos: {
maxColumns: 7,
allowedColumns: ['txid', 'address', 'scriptpubkey', 'output', 'value', 'blockheight', 'reserved']
} }
}; };

@ -29,7 +29,7 @@ $red-color: #c62828;
$red-background-color: #f8d7da; $red-background-color: #f8d7da;
$blue-color: #004085; $blue-color: #004085;
$blue-background-color: #cce5ff; $blue-background-color: #cce5ff;
$grey-color: #AAAAAA; $grey-color: #CCCCCC;
$tiny-dot-size: 0.8rem; $tiny-dot-size: 0.8rem;
$dot-size: 1.2rem; $dot-size: 1.2rem;
$badge-size: 0.8rem; $badge-size: 0.8rem;

@ -19,16 +19,16 @@ ORDER: Base + typography > general layout + grid > page layout > components
@mixin for_screensize($breakpoint) { @mixin for_screensize($breakpoint) {
@if $breakpoint == phone { @if $breakpoint == phone {
@media only screen and (max-width: 37.5em) { @content }; //600px @media only screen and (max-width: 60rem) { @content }; //600px
} }
@if $breakpoint == tab-port { @if $breakpoint == tab-port {
@media only screen and (max-width: 56.25em) { @content }; //900px @media only screen and (max-width: 90rem) { @content }; //900px
} }
@if $breakpoint == tab-land { @if $breakpoint == tab-land {
@media only screen and (max-width: 75em) { @content }; //1200px @media only screen and (max-width: 120rem) { @content }; //1200px
} }
@if $breakpoint == big-desktop { @if $breakpoint == big-desktop {
@media only screen and (min-width: 112.5em) { @content }; //1800 @media only screen and (min-width: 180rem) { @content }; //1800px
} }
} }

@ -258,19 +258,19 @@ mat-cell:last-of-type, mat-header-cell:last-of-type, mat-footer-cell:last-of-typ
} }
.green { .green {
color: #388e3c !important; color: $green-color !important;
} }
.yellow { .yellow {
color: #ffd740 !important; color: $yellow-color !important;
} }
.red { .red {
color: #c62828 !important; color: $red-color !important;
} }
.grey { .grey {
color: #CCCCCC !important; color: $grey-color !important;
} }
.mt-1px { .mt-1px {
@ -1538,11 +1538,11 @@ th.mat-header-cell:last-of-type, td.mat-cell:last-of-type, td.mat-footer-cell:la
text-align: left; text-align: left;
} }
.table-container { // .table-container {
// height: 400rem; // height: 25rem;
// overflow-y: auto; // overflow: auto;
// overflow-x: hidden; // overflow-x: hidden;
} // }
.mat-expansion-panel.flat-expansion-panel { .mat-expansion-panel.flat-expansion-panel {
box-shadow: none; box-shadow: none;

Loading…
Cancel
Save