+ block sorting even for unconfirmed empty blocks
* code for transactions table moved to separate unit
This commit is contained in:
184
assets/scripts/datatables-absolute.js
Normal file
184
assets/scripts/datatables-absolute.js
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/**
|
||||||
|
* When sorting a DataTable you might find that you want to keep a specific
|
||||||
|
* item at the top or bottom of the table. For example when sorting a column
|
||||||
|
* of numbers, if a value is `null` or `N/A` you might want to keep it at the
|
||||||
|
* bottom of the table, regardless of if ascending or descending sorting is
|
||||||
|
* applied. This plug-in provides that ability.
|
||||||
|
*
|
||||||
|
* You must call the `$.fn.dataTable.absoluteOrder` with information about the
|
||||||
|
* value(s) you wish to make absolute in the sorting order and store the
|
||||||
|
* returned value, assigning it to the `columns.type` option for the column
|
||||||
|
* you wish this sorting to be applied to.
|
||||||
|
*
|
||||||
|
* For number based columns a `$.fn.dataTable.absoluteOrderNumber` function is
|
||||||
|
* also available.
|
||||||
|
*
|
||||||
|
* @name Absolute sorting
|
||||||
|
* @summary Keep one or more items at the top and/or bottom of a table when sorting
|
||||||
|
* @author [Allan Jardine](//datatables.net)
|
||||||
|
* @depends DataTables 1.10+
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var namesType = $.fn.dataTable.absoluteOrder( [
|
||||||
|
* { value: '', position: 'top' }
|
||||||
|
* ] );
|
||||||
|
*
|
||||||
|
* var numbersType = $.fn.dataTable.absoluteOrderNumber( [
|
||||||
|
* { value: 'N/A', position: 'bottom' }
|
||||||
|
* ] );
|
||||||
|
*
|
||||||
|
* $('#example').DataTable( {
|
||||||
|
* columnDefs: [
|
||||||
|
* { type: namesType, targets: 0 },
|
||||||
|
* { type: numbersType, targets: 1 }
|
||||||
|
* ]
|
||||||
|
* } );
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function( factory ){
|
||||||
|
if ( typeof define === 'function' && define.amd ) {
|
||||||
|
// AMD
|
||||||
|
define( ['jquery', 'datatables.net'], function ( $ ) {
|
||||||
|
return factory( $, window, document );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
else if ( typeof exports === 'object' ) {
|
||||||
|
// CommonJS
|
||||||
|
module.exports = function (root, $) {
|
||||||
|
if ( ! root ) {
|
||||||
|
root = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $ || ! $.fn.dataTable ) {
|
||||||
|
$ = require('datatables.net')(root, $).$;
|
||||||
|
}
|
||||||
|
|
||||||
|
return factory( $, root, root.document );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Browser
|
||||||
|
factory( jQuery, window, document );
|
||||||
|
}
|
||||||
|
}(function( $, window, document, undefined ) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Unique value allowing multiple absolute ordering use cases on a single page.
|
||||||
|
var _unique = 0;
|
||||||
|
|
||||||
|
// Function to encapsulate code that is common to both the string and number
|
||||||
|
// ordering plug-ins.
|
||||||
|
var _setup = function ( values ) {
|
||||||
|
if ( ! $.isArray( values ) ) {
|
||||||
|
values = [ values ];
|
||||||
|
}
|
||||||
|
|
||||||
|
var o = {
|
||||||
|
name: 'absoluteOrder'+(_unique++),
|
||||||
|
alwaysTop: {},
|
||||||
|
alwaysBottom: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// In order to provide performance, the symbols that are to be looked for
|
||||||
|
// are stored as parameter keys in an object, allowing O(1) lookup, rather
|
||||||
|
// than O(n) if it were in an array.
|
||||||
|
for ( var i=0, ien=values.length ; i<ien ; i++ ) {
|
||||||
|
var conf = values[i];
|
||||||
|
|
||||||
|
if ( typeof conf === 'string' ) {
|
||||||
|
o.alwaysTop[ conf ] = true;
|
||||||
|
}
|
||||||
|
else if ( conf.position === undefined || conf.position === 'top' ) {
|
||||||
|
o.alwaysTop[ conf.value ] = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
o.alwaysBottom[ conf.value ] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ascending ordering method
|
||||||
|
o.asc = function ( a, b, isNumber ) {
|
||||||
|
if ( o.alwaysTop[ a ] && o.alwaysTop[ b ] ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if ( o.alwaysBottom[ a ] && o.alwaysBottom[ b ] ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if ( o.alwaysTop[ a ] || o.alwaysBottom[ b ] ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if ( o.alwaysBottom[ a ] || o.alwaysTop[ b ] ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isNumber ) {
|
||||||
|
// Cast as a number if required
|
||||||
|
if ( typeof a === 'string' ) {
|
||||||
|
a = a.replace(/[^\d\-\.]/g, '') * 1;
|
||||||
|
}
|
||||||
|
if ( typeof b === 'string' ) {
|
||||||
|
b = b.replace(/[^\d\-\.]/g, '') * 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Descending ordering method
|
||||||
|
o.desc = function ( a, b, isNumber ) {
|
||||||
|
if ( o.alwaysTop[ a ] && o.alwaysTop[ b ] ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if ( o.alwaysBottom[ a ] && o.alwaysBottom[ b ] ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if ( o.alwaysTop[ a ] || o.alwaysBottom[ b ] ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if ( o.alwaysBottom[ a ] || o.alwaysTop[ b ] ) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isNumber ) {
|
||||||
|
if ( typeof a === 'string' ) {
|
||||||
|
a = a.replace(/[^\d\-\.]/g, '') * 1;
|
||||||
|
}
|
||||||
|
if ( typeof b === 'string' ) {
|
||||||
|
b = b.replace(/[^\d\-\.]/g, '') * 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
|
||||||
|
};
|
||||||
|
|
||||||
|
return o;
|
||||||
|
};
|
||||||
|
|
||||||
|
// String based ordering
|
||||||
|
$.fn.dataTable.absoluteOrder = function ( values ) {
|
||||||
|
var conf = _setup( values );
|
||||||
|
|
||||||
|
$.fn.dataTable.ext.type.order[ conf.name+'-asc' ] = conf.asc;
|
||||||
|
$.fn.dataTable.ext.type.order[ conf.name+'-desc' ] = conf.desc;
|
||||||
|
|
||||||
|
// Return the name of the sorting plug-in that was created so it can be used
|
||||||
|
// with the `columns.type` parameter. There is no auto-detection here.
|
||||||
|
return conf.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Number based ordering - strips out everything but the number information
|
||||||
|
$.fn.dataTable.absoluteOrderNumber = function ( values ) {
|
||||||
|
var conf = _setup( values );
|
||||||
|
|
||||||
|
$.fn.dataTable.ext.type.order[ conf.name+'-asc' ] = function ( a, b ) {
|
||||||
|
return conf.asc( a, b, true );
|
||||||
|
};
|
||||||
|
$.fn.dataTable.ext.type.order[ conf.name+'-desc' ] = function ( a, b ) {
|
||||||
|
return conf.desc( a, b, true );
|
||||||
|
};
|
||||||
|
|
||||||
|
return conf.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}));
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<div id="transactionsWrapper">
|
<div id="transactionsWrapper">
|
||||||
|
<!----<button type="button" class="btn btn-etho" id="btnRefreshTransactions">Refresh</button>-->
|
||||||
<table id="tableTransactionsForAll" class="display tableTransactions" style="width:100%">
|
<table id="tableTransactionsForAll" class="display tableTransactions" style="width:100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
<script src="./assets/scripts/please-wait.js "></script>
|
<script src="./assets/scripts/please-wait.js "></script>
|
||||||
<script src="./assets/scripts/moment.min.js"></script>
|
<script src="./assets/scripts/moment.min.js"></script>
|
||||||
<script src="./assets/scripts/datetime-moment.js"></script>
|
<script src="./assets/scripts/datetime-moment.js"></script>
|
||||||
|
<script src="./assets/scripts/datatables-absolute.js"></script>
|
||||||
<script src="./assets/scripts/jquery.floatThead.min.js"></script>
|
<script src="./assets/scripts/jquery.floatThead.min.js"></script>
|
||||||
<script src="./assets/scripts/all.min.js"></script>
|
<script src="./assets/scripts/all.min.js"></script>
|
||||||
|
|
||||||
@@ -84,6 +85,7 @@
|
|||||||
require('./renderer/wallets.js');
|
require('./renderer/wallets.js');
|
||||||
require('./renderer/blockchain.js');
|
require('./renderer/blockchain.js');
|
||||||
require('./renderer/transactions.js');
|
require('./renderer/transactions.js');
|
||||||
|
require('./renderer/tableTransactions.js');
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const {app, ipcMain} = require('electron');
|
const {app, ipcMain} = require('electron');
|
||||||
const storage = require('electron-storage');
|
const storage = require('electron-storage');
|
||||||
const datastore = require('nedb');
|
const datastore = require('nedb');
|
||||||
|
const moment = require('moment');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const dbPath = path.join(app.getPath('userData'), 'storage.db');
|
const dbPath = path.join(app.getPath('userData'), 'storage.db');
|
||||||
@@ -26,9 +27,22 @@ ipcMain.on('storeTransaction', (event, arg) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('getTransactions', (event, arg) => {
|
ipcMain.on('getTransactions', (event, arg) => {
|
||||||
db.find({}).sort({ block: 1 }).exec(function (err, docs) {
|
db.find({}).exec(function (err, docs) {
|
||||||
ResultData = [];
|
ResultData = [];
|
||||||
|
|
||||||
|
// sort the data
|
||||||
|
docs.sort((a, b)=>{
|
||||||
|
if ((!b.block) && (a.block)) {
|
||||||
|
return 1;
|
||||||
|
} else if ((b.block) && (!a.block)) {
|
||||||
|
return -1;
|
||||||
|
} else if ((!b.block) && (!a.block)) {
|
||||||
|
return moment(b.timestamp, "YYYY-MM-DD HH:mm:ss").toDate() - moment(a.timestamp, "YYYY-MM-DD HH:mm:ss").toDate();
|
||||||
|
} else {
|
||||||
|
return b.block - a.block;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (i = 0; i < Math.min(docs.length, 500); i++) {
|
for (i = 0; i < Math.min(docs.length, 500); i++) {
|
||||||
ResultData.push([
|
ResultData.push([
|
||||||
docs[i].block,
|
docs[i].block,
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
"app-root-path": "^2.1.0",
|
"app-root-path": "^2.1.0",
|
||||||
"electron-storage": "^1.0.7",
|
"electron-storage": "^1.0.7",
|
||||||
"handlebars": "^4.0.12",
|
"handlebars": "^4.0.12",
|
||||||
|
"moment": "^2.23.0",
|
||||||
"nedb": "^1.8.0",
|
"nedb": "^1.8.0",
|
||||||
"single-instance": "0.0.1"
|
"single-instance": "0.0.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -145,13 +145,14 @@ $(document).on("render_send", function() {
|
|||||||
EthoMainGUI.showGeneralError(error);
|
EthoMainGUI.showGeneralError(error);
|
||||||
},
|
},
|
||||||
function(transaction) {
|
function(transaction) {
|
||||||
|
console.log(JSON.stringify(transaction));
|
||||||
ipcRenderer.send('storeTransaction', {
|
ipcRenderer.send('storeTransaction', {
|
||||||
block: element.block.toString(),
|
block: transaction.blockNumber,
|
||||||
txhash: element.hash.toLowerCase(),
|
txhash: transaction.hash.toLowerCase(),
|
||||||
fromaddr: element.fromaddr.toLowerCase(),
|
fromaddr: transaction.from.toLowerCase(),
|
||||||
timestamp: element.timestamp,
|
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
|
||||||
toaddr: element.toaddr.toLowerCase(),
|
toaddr: transaction.to.toLowerCase(),
|
||||||
value: element.value
|
value: transaction.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
73
renderer/tableTransactions.js
Normal file
73
renderer/tableTransactions.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
class tableTransactions {
|
||||||
|
constructor() {
|
||||||
|
this.appState = "account";
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize(id, data) {
|
||||||
|
// register the sort datetime format
|
||||||
|
$.fn.dataTable.moment('MMM Do YYYY HH:mm:ss');
|
||||||
|
|
||||||
|
var namesType = $.fn.dataTable.absoluteOrder(
|
||||||
|
[
|
||||||
|
{ value: null, position: 'top' }
|
||||||
|
]);
|
||||||
|
// render the transactions
|
||||||
|
$(id).DataTable({
|
||||||
|
"paging": false,
|
||||||
|
"scrollY": "calc(100vh - 115px)",
|
||||||
|
"responsive": true,
|
||||||
|
"processing": true,
|
||||||
|
"order": [[ 1, "desc" ]],
|
||||||
|
"data": data,
|
||||||
|
"oSearch": {"sSearch": EthoTransactions.getFilter() },
|
||||||
|
"columnDefs": [
|
||||||
|
{
|
||||||
|
"targets": 0,
|
||||||
|
"render": function ( data, type, row ) {
|
||||||
|
if (data == 0) {
|
||||||
|
return '<i class="fas fa-arrow-left"></i>';
|
||||||
|
} else if (data == 1) {
|
||||||
|
return '<i class="fas fa-arrow-right"></i>';
|
||||||
|
} else {
|
||||||
|
return '<i class="fas fa-arrows-alt-h"></i>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"className": "transactionsBlockNum",
|
||||||
|
"type": namesType,
|
||||||
|
"targets": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"targets": 2,
|
||||||
|
"render": function ( data, type, row ) {
|
||||||
|
return moment(data, "YYYY-MM-DD HH:mm:ss").format("MMM Do YYYY HH:mm:ss");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"targets": 5,
|
||||||
|
"render": function ( data, type, row ) {
|
||||||
|
return parseFloat(web3Local.utils.fromWei(EthoUtils.toFixed(parseFloat(data)).toString(), 'ether')).toFixed(2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"targets": 6,
|
||||||
|
"defaultContent": "",
|
||||||
|
"render": function ( data, type, row ) {
|
||||||
|
if (row[1]) {
|
||||||
|
return '<i class="fas fa-check"></i>';
|
||||||
|
} else {
|
||||||
|
return '<i class="fas fa-question"></i>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"drawCallback": function( settings ) {
|
||||||
|
$("#loadingTransactionsOverlay").css("display", "none");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new tables variable
|
||||||
|
EthoTableTransactions = new tableTransactions();
|
||||||
@@ -105,63 +105,7 @@ class Transactions {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// register the sort datetime format
|
EthoTableTransactions.initialize('#tableTransactionsForAll', dataTransactions);
|
||||||
$.fn.dataTable.moment('MMM Do YYYY HH:mm:ss');
|
|
||||||
|
|
||||||
// render the transactions
|
|
||||||
$('#tableTransactionsForAll').DataTable({
|
|
||||||
"paging": false,
|
|
||||||
"scrollY": "calc(100vh - 115px)",
|
|
||||||
"responsive": true,
|
|
||||||
"processing": true,
|
|
||||||
"order": [[ 1, "desc" ]],
|
|
||||||
"data": dataTransactions,
|
|
||||||
"oSearch": {"sSearch": EthoTransactions.getFilter() },
|
|
||||||
"columnDefs": [
|
|
||||||
{
|
|
||||||
"targets": 0,
|
|
||||||
"render": function ( data, type, row ) {
|
|
||||||
if (data == 0) {
|
|
||||||
return '<i class="fas fa-arrow-left"></i>';
|
|
||||||
} else if (data == 1) {
|
|
||||||
return '<i class="fas fa-arrow-right"></i>';
|
|
||||||
} else {
|
|
||||||
return '<i class="fas fa-arrows-alt-h"></i>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"className": "transactionsBlockNum",
|
|
||||||
"targets": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"targets": 2,
|
|
||||||
"render": function ( data, type, row ) {
|
|
||||||
return moment(data, "YYYY-MM-DD HH:mm:ss").format("MMM Do YYYY HH:mm:ss");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"targets": 5,
|
|
||||||
"render": function ( data, type, row ) {
|
|
||||||
return parseFloat(web3Local.utils.fromWei(EthoUtils.toFixed(parseFloat(data)).toString(), 'ether')).toFixed(2);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"targets": 6,
|
|
||||||
"defaultContent": "",
|
|
||||||
"render": function ( data, type, row ) {
|
|
||||||
if (row[1]) {
|
|
||||||
return '<i class="fas fa-check"></i>';
|
|
||||||
} else if (data == 1) {
|
|
||||||
return '<i class="fas fa-question"></i>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"drawCallback": function( settings ) {
|
|
||||||
$("#loadingTransactionsOverlay").css("display", "none");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,6 +150,10 @@ $(document).on("onSyncInterval", function() {
|
|||||||
// store transaction and notify about new transactions
|
// store transaction and notify about new transactions
|
||||||
ipcRenderer.send('storeTransaction', Transaction);
|
ipcRenderer.send('storeTransaction', Transaction);
|
||||||
$(document).trigger("onNewAccountTransaction");
|
$(document).trigger("onNewAccountTransaction");
|
||||||
|
|
||||||
|
if (EthoMainGUI.getAppState() == "transactions") {
|
||||||
|
//$('#tableTransactionsForAll').DataTable().ajax.reload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user