Merge pull request #132 from gerlofvanek/sort

ui: Sort on Time and Trade (table).
This commit is contained in:
Gerlof van Ek 2024-10-14 16:39:15 +02:00 committed by GitHub
commit 817d2c1e9c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 104 additions and 36 deletions

View file

@ -745,7 +745,7 @@ function updateProfitLoss(row, fromCoin, toCoin, fromAmount, toAmount, isOwnOffe
function createTableRow(offer, isSentOffers) { function createTableRow(offer, isSentOffers) {
const row = document.createElement('tr'); const row = document.createElement('tr');
row.className = `opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600`; row.className = `opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600`;
row.setAttribute('data-offer-id', offer.offer_id); row.setAttribute('data-offer-id', `${offer.offer_id}_${offer.created_at}`);
const coinFrom = offer.coin_from ? (symbolToCoinName[coinNameToSymbol[offer.coin_from]] || offer.coin_from) : 'Unknown'; const coinFrom = offer.coin_from ? (symbolToCoinName[coinNameToSymbol[offer.coin_from]] || offer.coin_from) : 'Unknown';
const coinTo = offer.coin_to ? (symbolToCoinName[coinNameToSymbol[offer.coin_to]] || offer.coin_to) : 'Unknown'; const coinTo = offer.coin_to ? (symbolToCoinName[coinNameToSymbol[offer.coin_to]] || offer.coin_to) : 'Unknown';

View file

@ -1170,37 +1170,103 @@ const app = {
console.log('Current BTC price:', app.btcPriceUSD); console.log('Current BTC price:', app.btcPriceUSD);
}, },
sortTable: (columnIndex) => { sortTable: (columnIndex) => {
const sortableColumns = [5, 6]; console.log(`Sorting column: ${columnIndex}`);
if (!sortableColumns.includes(columnIndex)) return; const sortableColumns = [1, 5, 6, 7]; // 1: Time, 5: Rate, 6: Market +/-, 7: Trade
const table = document.querySelector('table'); if (!sortableColumns.includes(columnIndex)) {
if (!table) { console.log(`Column ${columnIndex} is not sortable`);
console.error("Table not found for sorting."); return;
return; }
const table = document.querySelector('table');
if (!table) {
console.error("Table not found for sorting.");
return;
}
const rows = Array.from(table.querySelectorAll('tbody tr'));
console.log(`Found ${rows.length} rows to sort`);
const sortIcon = document.getElementById(`sort-icon-${columnIndex}`);
if (!sortIcon) {
console.error("Sort icon not found.");
return;
}
const sortOrder = sortIcon.textContent === '↓' ? 1 : -1;
sortIcon.textContent = sortOrder === 1 ? '↑' : '↓';
const getSafeTextContent = (element) => element ? element.textContent.trim() : '';
rows.sort((a, b) => {
let aValue, bValue;
switch (columnIndex) {
case 1: // Time column
aValue = getSafeTextContent(a.querySelector('td:first-child .text-xs:first-child'));
bValue = getSafeTextContent(b.querySelector('td:first-child .text-xs:first-child'));
// console.log(`Comparing times: "${aValue}" vs "${bValue}"`);
const parseTime = (timeStr) => {
const [value, unit] = timeStr.split(' ');
const numValue = parseFloat(value);
switch(unit) {
case 'seconds': return numValue;
case 'minutes': return numValue * 60;
case 'hours': return numValue * 3600;
case 'days': return numValue * 86400;
default: return 0;
}
};
return (parseTime(bValue) - parseTime(aValue)) * sortOrder;
case 5: // Rate
case 6: // Market +/-
aValue = getSafeTextContent(a.cells[columnIndex]);
bValue = getSafeTextContent(b.cells[columnIndex]);
console.log(`Comparing values: "${aValue}" vs "${bValue}"`);
aValue = parseFloat(aValue.replace(/[^\d.-]/g, '') || '0');
bValue = parseFloat(bValue.replace(/[^\d.-]/g, '') || '0');
return (aValue - bValue) * sortOrder;
case 7: // Trade
const aCell = a.cells[columnIndex];
const bCell = b.cells[columnIndex];
console.log('aCell:', aCell ? aCell.outerHTML : 'null');
console.log('bCell:', bCell ? bCell.outerHTML : 'null');
aValue = getSafeTextContent(aCell.querySelector('a')) ||
getSafeTextContent(aCell.querySelector('button')) ||
getSafeTextContent(aCell);
bValue = getSafeTextContent(bCell.querySelector('a')) ||
getSafeTextContent(bCell.querySelector('button')) ||
getSafeTextContent(bCell);
aValue = aValue.toLowerCase();
bValue = bValue.toLowerCase();
console.log(`Comparing trade actions: "${aValue}" vs "${bValue}"`);
if (aValue === bValue) return 0;
if (aValue === "swap") return -1 * sortOrder;
if (bValue === "swap") return 1 * sortOrder;
return aValue.localeCompare(bValue) * sortOrder;
default:
aValue = getSafeTextContent(a.cells[columnIndex]);
bValue = getSafeTextContent(b.cells[columnIndex]);
console.log(`Comparing default values: "${aValue}" vs "${bValue}"`);
return aValue.localeCompare(bValue, undefined, {
numeric: true,
sensitivity: 'base'
}) * sortOrder;
} }
const rows = Array.from(table.querySelectorAll('tbody tr')); });
const sortIcon = document.getElementById(`sort-icon-${columnIndex}`);
if (!sortIcon) { const tbody = table.querySelector('tbody');
console.error("Sort icon not found."); if (tbody) {
return; rows.forEach(row => tbody.appendChild(row));
} } else {
const sortOrder = sortIcon.textContent === '↓' ? 1 : -1; // console.error("Table body not found.");
sortIcon.textContent = sortOrder === 1 ? '↑' : '↓'; }
rows.sort((a, b) => { // console.log('Sorting completed');
const aValue = a.cells[columnIndex]?.textContent.trim() || ''; },
const bValue = b.cells[columnIndex]?.textContent.trim() || '';
return aValue.localeCompare(bValue, undefined, {
numeric: true,
sensitivity: 'base'
}) * sortOrder;
});
const tbody = table.querySelector('tbody');
if (tbody) {
rows.forEach(row => tbody.appendChild(row));
} else {
console.error("Table body not found.");
}
},
initializeSelectImages: () => { initializeSelectImages: () => {
const updateSelectedImage = (selectId) => { const updateSelectedImage = (selectId) => {

View file

@ -296,9 +296,10 @@ function getAPIKeys() {
<table class="w-full min-w-max"> <table class="w-full min-w-max">
<thead class="uppercase"> <thead class="uppercase">
<tr> <tr>
<th class="p-0"> <th class="p-0" data-sortable="true" data-column-index="0">
<div class="py-3 pl-4 justify-center rounded-tl-xl bg-coolGray-200 dark:bg-gray-600"> <div class="py-3 pl-4 justify-center rounded-tl-xl bg-coolGray-200 dark:bg-gray-600">
<span class="text-sm mr-1 text-gray-600 dark:text-gray-300 font-semibold">Time</span> <span class="text-sm mr-1 text-gray-600 dark:text-gray-300 font-semibold">Time</span>
<span class="sort-icon ml-1 text-gray-600 dark:text-gray-400" id="sort-icon-0"></span>
</div> </div>
</th> </th>
<th class="p-0 hidden xl:block"> <th class="p-0 hidden xl:block">
@ -349,11 +350,12 @@ function getAPIKeys() {
<span class="sort-icon ml-1 text-gray-600 dark:text-gray-400" id="sort-icon-6"></span> <span class="sort-icon ml-1 text-gray-600 dark:text-gray-400" id="sort-icon-6"></span>
</div> </div>
</th> </th>
<th class="p-0"> <th class="p-0" data-sortable="true" data-column-index="7">
<div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 rounded-tr-xl"> <div class="py-3 px-4 bg-coolGray-200 dark:bg-gray-600 rounded-tr-xl">
<span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Trade</span> <span class="text-sm text-gray-600 dark:text-gray-300 font-semibold">Trade</span>
</div> <span class="sort-icon ml-1 text-gray-600 dark:text-gray-400" id="sort-icon-7"></span>
</th> </div>
</th>
</tr> </tr>
</thead> </thead>
<tbody id="offers-body"> <tbody id="offers-body">