Merge pull request #404 from lbryio/ip/export-transactions

Transaction export: move file-creation to background.
This commit is contained in:
Thomas Zarebczan 2021-04-19 16:44:04 -04:00 committed by GitHub
commit 4e37ab6580
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 160 additions and 0 deletions

76
dist/bundle.es.js vendored
View file

@ -1934,6 +1934,63 @@ function doDismissError() {
};
}
// JSON parser
const parseJson = (data, filters = []) => {
const list = data.map(item => {
const temp = {};
// Apply filters
Object.entries(item).forEach(([key, value]) => {
if (!filters.includes(key)) temp[key] = value;
});
return temp;
});
// Beautify JSON
return JSON.stringify(list, null, '\t');
};
// CSV Parser
// No need for an external module:
// https://gist.github.com/btzr-io/55c3450ea3d709fc57540e762899fb85
const parseCsv = (data, filters = []) => {
// Get items for header
const getHeaders = item => {
const list = [];
// Apply filters
Object.entries(item).forEach(([key]) => {
if (!filters.includes(key)) list.push(key);
});
// return headers
return list.join(',');
};
// Get rows content
const getData = list => list.map(item => {
const row = [];
// Apply filters
Object.entries(item).forEach(([key, value]) => {
if (!filters.includes(key)) row.push(value);
});
// return rows
return row.join(',');
}).join('\n');
// Return CSV string
return `${getHeaders(data[0])} \n ${getData(data)}`;
};
const parseData = (data, format, filters = []) => {
// Check for validation
const valid = data && data[0] && format;
// Pick a format
const formats = {
csv: list => parseCsv(list, filters),
json: list => parseJson(list, filters)
};
// Return parsed data: JSON || CSV
return valid && formats[format] ? formats[format](data) : undefined;
};
const selectState = state => state.wallet || {};
const selectWalletState = selectState;
@ -2085,6 +2142,24 @@ const selectHasTransactions = reselect.createSelector(selectTransactionItems, tr
const selectIsFetchingTransactions = reselect.createSelector(selectState, state => state.fetchingTransactions);
/**
* CSV of 'selectTransactionItems'.
*/
const selectTransactionsFile = reselect.createSelector(selectTransactionItems, transactions => {
if (!transactions || transactions.length === 0) {
// No data.
return undefined;
}
const parsed = parseData(transactions, 'csv');
if (!parsed) {
// Invalid data, or failed to parse.
return null;
}
return parsed;
});
const selectIsSendingSupport = reselect.createSelector(selectState, state => state.sendingSupport);
const selectReceiveAddress = reselect.createSelector(selectState, state => state.receiveAddress);
@ -6793,6 +6868,7 @@ exports.selectTotalSupports = selectTotalSupports;
exports.selectTransactionItems = selectTransactionItems;
exports.selectTransactionListFilter = selectTransactionListFilter;
exports.selectTransactionsById = selectTransactionsById;
exports.selectTransactionsFile = selectTransactionsFile;
exports.selectTxoItemCount = selectTxoItemCount;
exports.selectTxoPage = selectTxoPage;
exports.selectTxoPageNumber = selectTxoPageNumber;

View file

@ -285,6 +285,7 @@ export {
selectSupportsByOutpoint,
selectTotalSupports,
selectTransactionItems,
selectTransactionsFile,
selectRecentTransactions,
selectHasTransactions,
selectIsFetchingTransactions,

View file

@ -2,6 +2,7 @@ import { createSelector } from 'reselect';
import * as TRANSACTIONS from 'constants/transaction_types';
import { PAGE_SIZE, LATEST_PAGE_SIZE } from 'constants/transaction_list';
import { selectClaimIdsByUri } from 'redux/selectors/claims';
import parseData from 'util/parse-data';
export const selectState = state => state.wallet || {};
export const selectWalletState = selectState;
@ -267,6 +268,27 @@ export const selectIsFetchingTransactions = createSelector(
state => state.fetchingTransactions
);
/**
* CSV of 'selectTransactionItems'.
*/
export const selectTransactionsFile = createSelector(
selectTransactionItems,
transactions => {
if (!transactions || transactions.length === 0) {
// No data.
return undefined;
}
const parsed = parseData(transactions, 'csv');
if (!parsed) {
// Invalid data, or failed to parse.
return null;
}
return parsed;
}
);
export const selectIsSendingSupport = createSelector(
selectState,
state => state.sendingSupport

61
src/util/parse-data.js Normal file
View file

@ -0,0 +1,61 @@
// JSON parser
const parseJson = (data, filters = []) => {
const list = data.map(item => {
const temp = {};
// Apply filters
Object.entries(item).forEach(([key, value]) => {
if (!filters.includes(key)) temp[key] = value;
});
return temp;
});
// Beautify JSON
return JSON.stringify(list, null, '\t');
};
// CSV Parser
// No need for an external module:
// https://gist.github.com/btzr-io/55c3450ea3d709fc57540e762899fb85
const parseCsv = (data, filters = []) => {
// Get items for header
const getHeaders = item => {
const list = [];
// Apply filters
Object.entries(item).forEach(([key]) => {
if (!filters.includes(key)) list.push(key);
});
// return headers
return list.join(',');
};
// Get rows content
const getData = list =>
list
.map(item => {
const row = [];
// Apply filters
Object.entries(item).forEach(([key, value]) => {
if (!filters.includes(key)) row.push(value);
});
// return rows
return row.join(',');
})
.join('\n');
// Return CSV string
return `${getHeaders(data[0])} \n ${getData(data)}`;
};
const parseData = (data, format, filters = []) => {
// Check for validation
const valid = data && data[0] && format;
// Pick a format
const formats = {
csv: list => parseCsv(list, filters),
json: list => parseJson(list, filters),
};
// Return parsed data: JSON || CSV
return valid && formats[format] ? formats[format](data) : undefined;
};
export default parseData;