major fixes for inventory
This commit is contained in:
parent
00ef1d1f4b
commit
4d19e29847
10 changed files with 969 additions and 203 deletions
|
|
@ -20,6 +20,11 @@ let currentSort = {
|
|||
// Store current search results for client-side sorting
|
||||
let currentResultsData = null;
|
||||
|
||||
// Pagination state
|
||||
let currentPage = 1;
|
||||
let itemsPerPage = 5000; // 5k items per page for good performance
|
||||
let totalPages = 1;
|
||||
|
||||
// Initialize the application
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Get DOM elements after DOM is loaded
|
||||
|
|
@ -39,7 +44,7 @@ function initializeEventListeners() {
|
|||
// Form submission
|
||||
searchForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
await performSearch();
|
||||
await performSearch(true); // Reset to page 1 on new search
|
||||
});
|
||||
|
||||
// Clear button
|
||||
|
|
@ -167,6 +172,10 @@ function clearAllFields() {
|
|||
// Reset slot filter
|
||||
document.getElementById('slotFilter').value = '';
|
||||
|
||||
// Reset pagination
|
||||
currentPage = 1;
|
||||
totalPages = 1;
|
||||
|
||||
// Reset results and clear stored data
|
||||
currentResultsData = null;
|
||||
searchResults.innerHTML = '<div class="no-results">Enter search criteria above and click "Search Items" to find inventory items.</div>';
|
||||
|
|
@ -196,7 +205,12 @@ function handleSlotFilterChange() {
|
|||
/**
|
||||
* Perform the search based on form inputs
|
||||
*/
|
||||
async function performSearch() {
|
||||
async function performSearch(resetPage = false) {
|
||||
// Reset to page 1 if this is a new search (not pagination)
|
||||
if (resetPage) {
|
||||
currentPage = 1;
|
||||
}
|
||||
|
||||
searchResults.innerHTML = '<div class="loading">🔍 Searching inventory...</div>';
|
||||
|
||||
try {
|
||||
|
|
@ -214,11 +228,13 @@ async function performSearch() {
|
|||
// Store results for client-side re-sorting
|
||||
currentResultsData = data;
|
||||
|
||||
// Update pagination state
|
||||
updatePaginationState(data);
|
||||
|
||||
// Apply client-side slot filtering
|
||||
applySlotFilter(data);
|
||||
|
||||
// Sort the results client-side before displaying
|
||||
sortResults(data);
|
||||
// Display results (already sorted by server)
|
||||
displayResults(data);
|
||||
|
||||
} catch (error) {
|
||||
|
|
@ -280,6 +296,8 @@ function buildSearchParameters() {
|
|||
addParam(params, 'max_damage_rating', 'searchMaxDamageRating');
|
||||
addParam(params, 'min_heal_boost_rating', 'searchMinHealBoost');
|
||||
addParam(params, 'max_heal_boost_rating', 'searchMaxHealBoost');
|
||||
addParam(params, 'min_vitality_rating', 'searchMinVitalityRating');
|
||||
addParam(params, 'min_damage_resist_rating', 'searchMinDamageResistRating');
|
||||
|
||||
// Requirements parameters
|
||||
addParam(params, 'min_level', 'searchMinLevel');
|
||||
|
|
@ -308,8 +326,19 @@ function buildSearchParameters() {
|
|||
params.append('legendary_cantrips', allSpells.join(','));
|
||||
}
|
||||
|
||||
// Pagination only - sorting will be done client-side
|
||||
params.append('limit', '1000'); // Show all items on one page
|
||||
// Equipment slot filters
|
||||
const selectedSlots = getSelectedSlots();
|
||||
if (selectedSlots.length > 0) {
|
||||
params.append('slot_names', selectedSlots.join(','));
|
||||
}
|
||||
|
||||
// Pagination parameters
|
||||
params.append('page', currentPage);
|
||||
params.append('limit', itemsPerPage);
|
||||
|
||||
// Sorting parameters
|
||||
params.append('sort_by', currentSort.field);
|
||||
params.append('sort_dir', currentSort.direction);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
|
@ -357,6 +386,22 @@ function getSelectedProtections() {
|
|||
return selectedProtections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get selected equipment slots from checkboxes
|
||||
*/
|
||||
function getSelectedSlots() {
|
||||
const selectedSlots = [];
|
||||
// Get armor slots
|
||||
document.querySelectorAll('#armor-slots input[type="checkbox"]:checked').forEach(cb => {
|
||||
selectedSlots.push(cb.value);
|
||||
});
|
||||
// Get jewelry slots
|
||||
document.querySelectorAll('#jewelry-slots input[type="checkbox"]:checked').forEach(cb => {
|
||||
selectedSlots.push(cb.value);
|
||||
});
|
||||
return selectedSlots;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display search results in the UI
|
||||
*/
|
||||
|
|
@ -383,12 +428,16 @@ function displayResults(data) {
|
|||
<th class="sortable" data-sort="character_name">Character${getSortIcon('character_name')}</th>
|
||||
<th class="sortable" data-sort="name">Item Name${getSortIcon('name')}</th>
|
||||
<th class="sortable" data-sort="item_type_name">Type${getSortIcon('item_type_name')}</th>
|
||||
<th class="text-right sortable" data-sort="slot_name">Slot${getSortIcon('slot_name')}</th>
|
||||
<th class="text-right sortable" data-sort="coverage">Coverage${getSortIcon('coverage')}</th>
|
||||
<th class="text-right sortable" data-sort="armor_level">Armor${getSortIcon('armor_level')}</th>
|
||||
<th class="sortable" data-sort="spell_names">Spells/Cantrips${getSortIcon('spell_names')}</th>
|
||||
<th class="text-right narrow-col sortable" data-sort="slot_name">Slot${getSortIcon('slot_name')}</th>
|
||||
<th class="text-right narrow-col sortable" data-sort="coverage">Coverage${getSortIcon('coverage')}</th>
|
||||
<th class="text-right sortable" data-sort="armor">Armor${getSortIcon('armor')}</th>
|
||||
<th class="set-col sortable" data-sort="item_set">Set${getSortIcon('item_set')}</th>
|
||||
<th class="medium-col sortable" data-sort="spell_names">Spells/Cantrips${getSortIcon('spell_names')}</th>
|
||||
<th class="text-right sortable" data-sort="crit_damage_rating">Crit Dmg${getSortIcon('crit_damage_rating')}</th>
|
||||
<th class="text-right sortable" data-sort="damage_rating">Dmg Rating${getSortIcon('damage_rating')}</th>
|
||||
<th class="text-right sortable" data-sort="heal_boost_rating">Heal Boost${getSortIcon('heal_boost_rating')}</th>
|
||||
<th class="text-right sortable" data-sort="vitality_rating">Vitality${getSortIcon('vitality_rating')}</th>
|
||||
<th class="text-right sortable" data-sort="damage_resist_rating">Dmg Resist${getSortIcon('damage_resist_rating')}</th>
|
||||
<th class="text-right sortable" data-sort="last_updated">Last Updated${getSortIcon('last_updated')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
@ -399,14 +448,19 @@ function displayResults(data) {
|
|||
const armor = item.armor_level > 0 ? item.armor_level : '-';
|
||||
const critDmg = item.crit_damage_rating > 0 ? item.crit_damage_rating : '-';
|
||||
const dmgRating = item.damage_rating > 0 ? item.damage_rating : '-';
|
||||
const healBoostRating = item.heal_boost_rating > 0 ? item.heal_boost_rating : '-';
|
||||
const vitalityRating = item.vitality_rating > 0 ? item.vitality_rating : '-';
|
||||
const damageResistRating = item.damage_resist_rating > 0 ? item.damage_resist_rating : '-';
|
||||
const status = item.is_equipped ? '⚔️ Equipped' : '📦 Inventory';
|
||||
const statusClass = item.is_equipped ? 'status-equipped' : 'status-inventory';
|
||||
|
||||
// Use the slot_name provided by the API instead of incorrect mapping
|
||||
const slot = item.slot_name || 'Unknown';
|
||||
// Replace commas with line breaks for better display
|
||||
const slot = item.slot_name ? item.slot_name.replace(/,\s*/g, '<br>') : 'Unknown';
|
||||
|
||||
// Coverage placeholder - will need to be added to backend later
|
||||
const coverage = item.coverage || '-';
|
||||
// Replace commas with line breaks for better display
|
||||
const coverage = item.coverage ? item.coverage.replace(/,\s*/g, '<br>') : '-';
|
||||
|
||||
// Format last updated timestamp
|
||||
const lastUpdated = item.last_updated ?
|
||||
|
|
@ -444,17 +498,30 @@ function displayResults(data) {
|
|||
// Get item type for display
|
||||
const itemType = item.item_type_name || '-';
|
||||
|
||||
// Format equipment set name
|
||||
let setDisplay = '-';
|
||||
if (item.item_set) {
|
||||
// Remove redundant "Set" prefix if present
|
||||
setDisplay = item.item_set.replace(/^Set\s+/i, '');
|
||||
// Also handle if it ends with " Set"
|
||||
setDisplay = setDisplay.replace(/\s+Set$/i, '');
|
||||
}
|
||||
|
||||
html += `
|
||||
<tr>
|
||||
<td>${item.character_name}</td>
|
||||
<td class="item-name">${displayName}</td>
|
||||
<td>${itemType}</td>
|
||||
<td class="text-right">${slot}</td>
|
||||
<td class="text-right">${coverage}</td>
|
||||
<td class="text-right narrow-col">${slot}</td>
|
||||
<td class="text-right narrow-col">${coverage}</td>
|
||||
<td class="text-right">${armor}</td>
|
||||
<td class="spells-cell">${spellsDisplay}</td>
|
||||
<td class="set-col" title="${setDisplay}">${setDisplay}</td>
|
||||
<td class="spells-cell medium-col">${spellsDisplay}</td>
|
||||
<td class="text-right">${critDmg}</td>
|
||||
<td class="text-right">${dmgRating}</td>
|
||||
<td class="text-right">${healBoostRating}</td>
|
||||
<td class="text-right">${vitalityRating}</td>
|
||||
<td class="text-right">${damageResistRating}</td>
|
||||
<td class="text-right">${lastUpdated}</td>
|
||||
</tr>
|
||||
`;
|
||||
|
|
@ -465,11 +532,18 @@ function displayResults(data) {
|
|||
</table>
|
||||
`;
|
||||
|
||||
// Add pagination info if needed
|
||||
if (data.total_pages > 1) {
|
||||
// Add pagination controls if needed
|
||||
if (totalPages > 1) {
|
||||
const isFirstPage = currentPage === 1;
|
||||
const isLastPage = currentPage === totalPages;
|
||||
|
||||
html += `
|
||||
<div style="padding: 16px 24px; text-align: center; color: #5f6368; border-top: 1px solid #e8eaed;">
|
||||
Showing page ${data.page} of ${data.total_pages} pages
|
||||
<div class="pagination-controls">
|
||||
<button onclick="goToPage(1)" ${isFirstPage ? 'disabled' : ''}>First</button>
|
||||
<button onclick="previousPage()" ${isFirstPage ? 'disabled' : ''}>← Previous</button>
|
||||
<span class="pagination-info">Page ${currentPage} of ${totalPages} (${data.total_count} total items)</span>
|
||||
<button onclick="nextPage()" ${isLastPage ? 'disabled' : ''}>Next →</button>
|
||||
<button onclick="goToPage(${totalPages})" ${isLastPage ? 'disabled' : ''}>Last</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
|
@ -566,20 +640,9 @@ function handleSort(field) {
|
|||
currentSort.direction = 'asc';
|
||||
}
|
||||
|
||||
// Re-display current results with new sorting (no new search needed)
|
||||
if (currentResultsData) {
|
||||
// Reset items to original unfiltered data
|
||||
const originalData = JSON.parse(JSON.stringify(currentResultsData));
|
||||
|
||||
// Apply slot filtering first
|
||||
applySlotFilter(originalData);
|
||||
|
||||
// Then apply sorting
|
||||
sortResults(originalData);
|
||||
|
||||
// Display results
|
||||
displayResults(originalData);
|
||||
}
|
||||
// Reset to page 1 and perform new search with updated sort
|
||||
currentPage = 1;
|
||||
performSearch();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -722,3 +785,41 @@ function displaySetAnalysisResults(data) {
|
|||
|
||||
setAnalysisResults.innerHTML = html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update pagination state from API response
|
||||
*/
|
||||
function updatePaginationState(data) {
|
||||
totalPages = data.total_pages || 1;
|
||||
// Current page is already tracked in currentPage
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to a specific page
|
||||
*/
|
||||
function goToPage(page) {
|
||||
if (page < 1 || page > totalPages || page === currentPage) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentPage = page;
|
||||
performSearch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to next page
|
||||
*/
|
||||
function nextPage() {
|
||||
if (currentPage < totalPages) {
|
||||
goToPage(currentPage + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to previous page
|
||||
*/
|
||||
function previousPage() {
|
||||
if (currentPage > 1) {
|
||||
goToPage(currentPage - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue