mirror of
https://github.com/basicswap/basicswap.git
synced 2025-04-06 14:27:30 +00:00
Add CSV export on bids page + various fixes.
This commit is contained in:
parent
033b0a1583
commit
06d37a2e54
2 changed files with 163 additions and 5 deletions
basicswap
141
basicswap/static/js/bids_export.js
Normal file
141
basicswap/static/js/bids_export.js
Normal file
|
@ -0,0 +1,141 @@
|
|||
const BidExporter = {
|
||||
toCSV(bids, type) {
|
||||
if (!bids || !bids.length) {
|
||||
return 'No data to export';
|
||||
}
|
||||
|
||||
const isSent = type === 'sent';
|
||||
|
||||
const headers = [
|
||||
'Date/Time',
|
||||
'Bid ID',
|
||||
'Offer ID',
|
||||
'From Address',
|
||||
isSent ? 'You Send Amount' : 'You Receive Amount',
|
||||
isSent ? 'You Send Coin' : 'You Receive Coin',
|
||||
isSent ? 'You Receive Amount' : 'You Send Amount',
|
||||
isSent ? 'You Receive Coin' : 'You Send Coin',
|
||||
'Status',
|
||||
'Created At',
|
||||
'Expires At'
|
||||
];
|
||||
|
||||
let csvContent = headers.join(',') + '\n';
|
||||
|
||||
bids.forEach(bid => {
|
||||
const row = [
|
||||
`"${formatTime(bid.created_at)}"`,
|
||||
`"${bid.bid_id}"`,
|
||||
`"${bid.offer_id}"`,
|
||||
`"${bid.addr_from}"`,
|
||||
isSent ? bid.amount_from : bid.amount_to,
|
||||
`"${isSent ? bid.coin_from : bid.coin_to}"`,
|
||||
isSent ? bid.amount_to : bid.amount_from,
|
||||
`"${isSent ? bid.coin_to : bid.coin_from}"`,
|
||||
`"${bid.bid_state}"`,
|
||||
bid.created_at,
|
||||
bid.expire_at
|
||||
];
|
||||
|
||||
csvContent += row.join(',') + '\n';
|
||||
});
|
||||
|
||||
return csvContent;
|
||||
},
|
||||
|
||||
download(content, filename) {
|
||||
try {
|
||||
const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' });
|
||||
|
||||
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
|
||||
window.navigator.msSaveOrOpenBlob(blob, filename);
|
||||
return;
|
||||
}
|
||||
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
|
||||
link.href = url;
|
||||
link.download = filename;
|
||||
link.style.display = 'none';
|
||||
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
setTimeout(() => {
|
||||
URL.revokeObjectURL(url);
|
||||
}, 100);
|
||||
} catch (error) {
|
||||
console.error('Error downloading CSV:', error);
|
||||
|
||||
const csvData = 'data:text/csv;charset=utf-8,' + encodeURIComponent(content);
|
||||
const link = document.createElement('a');
|
||||
link.setAttribute('href', csvData);
|
||||
link.setAttribute('download', filename);
|
||||
link.style.display = 'none';
|
||||
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
},
|
||||
|
||||
exportCurrentView() {
|
||||
const type = state.currentTab;
|
||||
const data = state.data[type];
|
||||
|
||||
if (!data || !data.length) {
|
||||
alert('No data to export');
|
||||
return;
|
||||
}
|
||||
|
||||
const csvContent = this.toCSV(data, type);
|
||||
|
||||
const now = new Date();
|
||||
const dateStr = now.toISOString().split('T')[0];
|
||||
const filename = `${type}_bids_${dateStr}.csv`;
|
||||
|
||||
this.download(csvContent, filename);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setTimeout(function() {
|
||||
if (typeof state !== 'undefined' && typeof EventManager !== 'undefined') {
|
||||
const exportSentButton = document.getElementById('exportSentBids');
|
||||
if (exportSentButton) {
|
||||
EventManager.add(exportSentButton, 'click', (e) => {
|
||||
e.preventDefault();
|
||||
state.currentTab = 'sent';
|
||||
BidExporter.exportCurrentView();
|
||||
});
|
||||
}
|
||||
|
||||
const exportReceivedButton = document.getElementById('exportReceivedBids');
|
||||
if (exportReceivedButton) {
|
||||
EventManager.add(exportReceivedButton, 'click', (e) => {
|
||||
e.preventDefault();
|
||||
state.currentTab = 'received';
|
||||
BidExporter.exportCurrentView();
|
||||
});
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
const originalCleanup = window.cleanup || function(){};
|
||||
window.cleanup = function() {
|
||||
originalCleanup();
|
||||
|
||||
const exportSentButton = document.getElementById('exportSentBids');
|
||||
const exportReceivedButton = document.getElementById('exportReceivedBids');
|
||||
|
||||
if (exportSentButton && typeof EventManager !== 'undefined') {
|
||||
EventManager.remove(exportSentButton, 'click');
|
||||
}
|
||||
|
||||
if (exportReceivedButton && typeof EventManager !== 'undefined') {
|
||||
EventManager.remove(exportReceivedButton, 'click');
|
||||
}
|
||||
};
|
|
@ -1,9 +1,9 @@
|
|||
{% include 'header.html' %}
|
||||
{% from 'style.html' import breadcrumb_line_svg, page_back_svg, page_forwards_svg, filter_clear_svg, filter_apply_svg, circular_arrows_svg, input_arrow_down_svg, arrow_right_svg %}
|
||||
|
||||
<div class="xl:container mx-auto">
|
||||
<section class="py-3 px-4 mt-6">
|
||||
<div class="xl:container mx-auto">
|
||||
|
||||
<section class="py-3 px-4 mt-6">
|
||||
<div class="lg:container mx-auto">
|
||||
<div class="relative py-8 px-8 bg-coolGray-900 dark:bg-blue-500 rounded-md overflow-hidden">
|
||||
<img class="absolute z-10 left-4 top-4" src="/static/images/elements/dots-red.svg" alt="">
|
||||
<img class="absolute z-10 right-4 bottom-4" src="/static/images/elements/dots-red.svg" alt="">
|
||||
|
@ -20,6 +20,7 @@
|
|||
|
||||
{% include 'inc_messages.html' %}
|
||||
|
||||
<div class="xl:container mx-auto">
|
||||
<section>
|
||||
<div class="pl-6 pr-6 pt-0 mt-5 h-full overflow-hidden">
|
||||
<div class="flex flex-wrap items-center justify-between -m-2">
|
||||
|
@ -42,6 +43,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<div class="px-6 py-0 h-full overflow-hidden">
|
||||
|
@ -229,6 +231,14 @@
|
|||
<span id="refreshSentText">Refresh</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
<button id="exportSentBids" class="ml-4 inline-flex items-center px-4 py-2.5 font-medium text-sm text-white bg-green-600 hover:bg-green-700 hover:border-green-700 rounded-lg transition duration-200 border border-green-600 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
<span>Export CSV</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div id="pagination-controls-sent" class="flex items-center space-x-2" style="display: none;">
|
||||
<button id="prevPageSent" class="inline-flex items-center h-9 py-1 px-4 text-xs text-blue-50 font-semibold bg-blue-500 hover:bg-green-600 rounded-lg transition duration-200 focus:ring-0 focus:outline-none">
|
||||
|
@ -254,7 +264,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Received Bids Tab -->
|
||||
<div class="hidden rounded-lg lg:px-6" id="received" role="tabpanel" aria-labelledby="received-tab">
|
||||
<div id="received-content">
|
||||
<div class="xl:container mx-auto lg:px-0">
|
||||
|
@ -319,6 +328,14 @@
|
|||
<span id="refreshReceivedText">Refresh</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
<button id="exportReceivedBids" class="ml-4 inline-flex items-center px-4 py-2.5 font-medium text-sm text-white bg-green-600 hover:bg-green-700 hover:border-green-700 rounded-lg transition duration-200 border border-green-600 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
<span>Export CSV</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div id="pagination-controls-received" class="flex items-center space-x-2" style="display: none;">
|
||||
<button id="prevPageReceived" class="inline-flex items-center h-9 py-1 px-4 text-xs text-blue-50 font-semibold bg-blue-500 hover:bg-green-600 rounded-lg transition duration-200 focus:ring-0 focus:outline-none">
|
||||
|
@ -344,8 +361,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/bids_sentreceived.js"></script>
|
||||
<script src="/static/js/bids_export.js"></script>
|
||||
|
||||
{% include 'footer.html' %}
|
||||
|
|
Loading…
Reference in a new issue