fix: exporting issues (#1163)

This commit is contained in:
Baltazar Gomez 2018-03-22 08:43:35 -07:00 committed by Igor Gassmann
parent de2cbe5f77
commit fcdb935687
8 changed files with 83 additions and 37 deletions

View file

@ -12,7 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
* Notifications when the channel a user subscribes to uploads new content ([#1066](https://github.com/lbryio/lbry-app/pull/1066)) * Notifications when the channel a user subscribes to uploads new content ([#1066](https://github.com/lbryio/lbry-app/pull/1066))
* Codacy support for Github contributions ([#1059](https://github.com/lbryio/lbry-app/pull/1059)) * Codacy support for Github contributions ([#1059](https://github.com/lbryio/lbry-app/pull/1059))
* App category for Linux ([#877](https://github.com/lbryio/lbry-app/pull/877)) * App category for Linux ([#877](https://github.com/lbryio/lbry-app/pull/877))
* Add YouTube Sync reward ([1147](https://github.com/lbryio/lbry-app/pull/1147)) * Add YouTube Sync reward ([#1147](https://github.com/lbryio/lbry-app/pull/1147))
* Retain previous screen sizing on startup ([#338](https://github.com/lbryio/lbry-app/issues/338)) * Retain previous screen sizing on startup ([#338](https://github.com/lbryio/lbry-app/issues/338))
### Changed ### Changed
@ -25,8 +25,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
* Do not kill an existing daemon, instead check if one exists ([#973](https://github.com/lbryio/lbry-app/pull/973)) * Do not kill an existing daemon, instead check if one exists ([#973](https://github.com/lbryio/lbry-app/pull/973))
* Enable play button immediately after user clicks download ([#987](https://github.com/lbryio/lbry-app/pull/987)) * Enable play button immediately after user clicks download ([#987](https://github.com/lbryio/lbry-app/pull/987))
* Significantly improved search performance ([#1032](https://github.com/lbryio/lbry-app/pull/1032)) * Significantly improved search performance ([#1032](https://github.com/lbryio/lbry-app/pull/1032))
* Allow editing of claims when bid is greater than current balance ([1105](https://github.com/lbryio/lbry-app/pull/1105)) * Allow editing of claims when bid is greater than current balance ([#1105](https://github.com/lbryio/lbry-app/pull/1105))
### Fixed ### Fixed
* Fixed sort by date of published content ([#986](https://github.com/lbryio/lbry-app/issues/986)) * Fixed sort by date of published content ([#986](https://github.com/lbryio/lbry-app/issues/986))
* Fix night mode start time, set to 9PM ([#1050](https://github.com/lbryio/lbry-app/issues/1050)) * Fix night mode start time, set to 9PM ([#1050](https://github.com/lbryio/lbry-app/issues/1050))
@ -39,7 +39,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
* App will no longer reset when minimizing to tray ([#1042](https://github.com/lbryio/lbry-app/pull/1042)) * App will no longer reset when minimizing to tray ([#1042](https://github.com/lbryio/lbry-app/pull/1042))
* Error when clicking LBRY URLs when app is closed on macOS ([#1119](https://github.com/lbryio/lbry-app/issues/1119)) * Error when clicking LBRY URLs when app is closed on macOS ([#1119](https://github.com/lbryio/lbry-app/issues/1119))
* LBRY URLs not working on Linux ([#1120](https://github.com/lbryio/lbry-app/issues/1120)) * LBRY URLs not working on Linux ([#1120](https://github.com/lbryio/lbry-app/issues/1120))
* Fix Windows notifications not showing ([1145](https://github.com/lbryio/lbry-app/pull/1145)) * Fix Windows notifications not showing ([#1145](https://github.com/lbryio/lbry-app/pull/1145))
* Fix export issues ([#1163](https://github.com/lbryio/lbry-app/pull/1163))
* Fix __static path not resolving on development environment * Fix __static path not resolving on development environment
### Deprecated ### Deprecated

View file

@ -12,10 +12,15 @@ class FileExporter extends React.PureComponent {
data: PropTypes.array, data: PropTypes.array,
title: PropTypes.string, title: PropTypes.string,
label: PropTypes.string, label: PropTypes.string,
filters: PropTypes.arrayOf(PropTypes.string),
defaultPath: PropTypes.string, defaultPath: PropTypes.string,
onFileCreated: PropTypes.func, onFileCreated: PropTypes.func,
}; };
static defaultProps = {
filters: [],
};
constructor(props) { constructor(props) {
super(props); super(props);
} }
@ -30,12 +35,21 @@ class FileExporter extends React.PureComponent {
} }
handleButtonClick() { handleButtonClick() {
const { title, defaultPath, data } = this.props; const { title, data, defaultPath, filters } = this.props;
const options = { const options = {
title, title,
defaultPath, defaultPath,
filters: [{ name: 'JSON', extensions: ['json'] }, { name: 'CSV', extensions: ['csv'] }], filters: [
{
name: 'CSV',
extensions: ['csv'],
},
{
name: 'JSON',
extensions: ['json'],
},
],
}; };
remote.dialog.showSaveDialog(options, filename => { remote.dialog.showSaveDialog(options, filename => {
@ -44,7 +58,7 @@ class FileExporter extends React.PureComponent {
// Get extension and remove initial dot // Get extension and remove initial dot
const format = path.extname(filename).replace(/\./g, ''); const format = path.extname(filename).replace(/\./g, '');
// Parse data to string with the chosen format // Parse data to string with the chosen format
const parsed = parseData(data, format); const parsed = parseData(data, format, filters);
// Write file // Write file
parsed && this.handleFileCreation(filename, parsed); parsed && this.handleFileCreation(filename, parsed);
}); });

View file

@ -62,8 +62,10 @@ class ChannelSection extends React.PureComponent {
return; return;
} }
if (newChannelBid === balance) { if (newChannelBid === balance) {
this.refs.newChannelName.showError(__('Please decrease your bid to account for transaction fees.')); this.refs.newChannelName.showError(
__('Please decrease your bid to account for transaction fees.')
);
return; return;
} }

View file

@ -47,8 +47,10 @@ class TransactionList extends React.PureComponent {
{Boolean(transactionList.length) && ( {Boolean(transactionList.length) && (
<FileExporter <FileExporter
data={transactionList} data={transactionList}
title={__('Export Transactions')}
label={__('Export')} label={__('Export')}
title={__('Export Transactions')}
filters={['nout']}
defaultPath={__('lbry-transactions-history')}
/> />
)} )}
{(transactionList.length || this.state.filter) && ( {(transactionList.length || this.state.filter) && (

View file

@ -99,9 +99,9 @@ const init = () => {
app.store.dispatch(doAutoUpdate()); app.store.dispatch(doAutoUpdate());
}); });
autoUpdater.on('error', (error) => { autoUpdater.on('error', error => {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error(error.message) console.error(error.message);
}); });
if (['win32', 'darwin'].includes(process.platform)) { if (['win32', 'darwin'].includes(process.platform)) {

View file

@ -43,18 +43,22 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => {
const byId = Object.assign({}, state.byId); const byId = Object.assign({}, state.byId);
const pendingById = Object.assign({}, state.pendingById); const pendingById = Object.assign({}, state.pendingById);
claims.filter(claim => claim.category && (claim.category.match(/claim/) || claim.category.match(/update/))).forEach(claim => { claims
byId[claim.claim_id] = claim; .filter(
claim => claim.category && (claim.category.match(/claim/) || claim.category.match(/update/))
)
.forEach(claim => {
byId[claim.claim_id] = claim;
const pending = Object.values(pendingById).find( const pending = Object.values(pendingById).find(
pendingClaim => pendingClaim =>
pendingClaim.name === claim.name && pendingClaim.channel_name === claim.channel_name pendingClaim.name === claim.name && pendingClaim.channel_name === claim.channel_name
); );
if (pending) { if (pending) {
delete pendingById[pending.claim_id]; delete pendingById[pending.claim_id];
} }
}); });
// Remove old timed out pending publishes // Remove old timed out pending publishes
Object.values(pendingById) Object.values(pendingById)

View file

@ -39,7 +39,7 @@ rewards.SORT_ORDER = [
rewards.TYPE_MANY_DOWNLOADS, rewards.TYPE_MANY_DOWNLOADS,
rewards.TYPE_REFERRAL, rewards.TYPE_REFERRAL,
rewards.TYPE_NEW_DEVELOPER, rewards.TYPE_NEW_DEVELOPER,
rewards.YOUTUBE_CREATOR rewards.YOUTUBE_CREATOR,
]; ];
rewards.claimReward = type => { rewards.claimReward = type => {

View file

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