fix: exporting issues (#1163)
This commit is contained in:
parent
de2cbe5f77
commit
fcdb935687
8 changed files with 83 additions and 37 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) && (
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue