major fixes for inventory
This commit is contained in:
parent
00ef1d1f4b
commit
4d19e29847
10 changed files with 969 additions and 203 deletions
|
|
@ -88,6 +88,13 @@
|
|||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Player Dashboard link -->
|
||||
<div class="player-dashboard-link">
|
||||
<a href="#" id="playerDashboardBtn" onclick="openPlayerDashboard()">
|
||||
👥 Player Dashboard
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Container for sort and filter controls -->
|
||||
<div id="sortButtons" class="sort-buttons"></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -170,6 +170,14 @@
|
|||
color: #000;
|
||||
}
|
||||
|
||||
.subsection-label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 2px;
|
||||
display: block;
|
||||
font-size: 9px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.search-actions {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
|
|
@ -325,6 +333,79 @@
|
|||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Column width control */
|
||||
.narrow-col {
|
||||
width: 120px;
|
||||
max-width: 120px;
|
||||
font-size: 9px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.medium-col {
|
||||
width: 150px;
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.set-col {
|
||||
width: 100px;
|
||||
max-width: 100px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.spells-cell {
|
||||
font-size: 9px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.legendary-cantrip {
|
||||
color: #ffd700;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.regular-spell {
|
||||
color: #88ccff;
|
||||
}
|
||||
|
||||
/* Pagination controls */
|
||||
.pagination-controls {
|
||||
padding: 12px 16px;
|
||||
text-align: center;
|
||||
background: #f8f8f8;
|
||||
border-top: 1px solid #ddd;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.pagination-controls button {
|
||||
padding: 4px 8px;
|
||||
border: 1px solid #999;
|
||||
background: #e0e0e0;
|
||||
font-size: 10px;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.pagination-controls button:hover:not(:disabled) {
|
||||
background: #d0d0d0;
|
||||
}
|
||||
|
||||
.pagination-controls button:disabled {
|
||||
background: #f0f0f0;
|
||||
color: #999;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.pagination-info {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin: 0 15px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -442,6 +523,18 @@
|
|||
<input type="number" id="searchMaxHealBoost" placeholder="Max">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New Rating Filters -->
|
||||
<div class="filter-row">
|
||||
<div class="filter-group">
|
||||
<label>Vitality:</label>
|
||||
<input type="number" id="searchMinVitalityRating" placeholder="Min">
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>Dmg Resist:</label>
|
||||
<input type="number" id="searchMinDamageResistRating" placeholder="Min">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Equipment Sets -->
|
||||
<div class="filter-section">
|
||||
|
|
@ -545,54 +638,148 @@
|
|||
</div>
|
||||
<!-- Legendary Weapon Skills -->
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_finesse" value="Legendary Finesse Weapons">
|
||||
<input type="checkbox" id="cantrip_legendary_finesse" value="Legendary Finesse Weapon Aptitude">
|
||||
<label for="cantrip_legendary_finesse">Finesse</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_heavy" value="Legendary Heavy Weapons">
|
||||
<input type="checkbox" id="cantrip_legendary_heavy" value="Legendary Heavy Weapon Aptitude">
|
||||
<label for="cantrip_legendary_heavy">Heavy</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_light" value="Legendary Light Weapons">
|
||||
<input type="checkbox" id="cantrip_legendary_light" value="Legendary Light Weapon Aptitude">
|
||||
<label for="cantrip_legendary_light">Light</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_missile" value="Legendary Missile Weapons">
|
||||
<input type="checkbox" id="cantrip_legendary_missile" value="Legendary Missile Weapon Aptitude">
|
||||
<label for="cantrip_legendary_missile">Missile</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_twohanded" value="Legendary Two Handed Combat">
|
||||
<input type="checkbox" id="cantrip_legendary_twohanded" value="Legendary Two Handed Combat Aptitude">
|
||||
<label for="cantrip_legendary_twohanded">Two-handed</label>
|
||||
</div>
|
||||
<!-- Legendary Magic Skills -->
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_war" value="Legendary War Magic">
|
||||
<input type="checkbox" id="cantrip_legendary_war" value="Legendary War Magic Aptitude">
|
||||
<label for="cantrip_legendary_war">War Magic</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_void" value="Legendary Void Magic">
|
||||
<input type="checkbox" id="cantrip_legendary_void" value="Legendary Void Magic Aptitude">
|
||||
<label for="cantrip_legendary_void">Void Magic</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_creature" value="Legendary Creature Enchantment">
|
||||
<input type="checkbox" id="cantrip_legendary_creature" value="Legendary Creature Enchantment Aptitude">
|
||||
<label for="cantrip_legendary_creature">Creature</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_item" value="Legendary Item Enchantment">
|
||||
<input type="checkbox" id="cantrip_legendary_item" value="Legendary Item Enchantment Aptitude">
|
||||
<label for="cantrip_legendary_item">Item</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_life" value="Legendary Life Magic">
|
||||
<input type="checkbox" id="cantrip_legendary_life" value="Legendary Life Magic Aptitude">
|
||||
<label for="cantrip_legendary_life">Life Magic</label>
|
||||
</div>
|
||||
<!-- Legendary Defense -->
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_magic_defense" value="Legendary Magic Defense">
|
||||
<input type="checkbox" id="cantrip_legendary_magic_defense" value="Legendary Magic Resistance">
|
||||
<label for="cantrip_legendary_magic_defense">Magic Def</label>
|
||||
</div>
|
||||
|
||||
<!-- Combat Skills -->
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_melee_defense" value="Legendary Melee Defense">
|
||||
<label for="cantrip_legendary_melee_defense">Melee Def</label>
|
||||
<input type="checkbox" id="cantrip_legendary_blood_thirst" value="Legendary Blood Thirst">
|
||||
<label for="cantrip_legendary_blood_thirst">Blood Thirst</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_sneak_attack" value="Legendary Sneak Attack Prowess">
|
||||
<label for="cantrip_legendary_sneak_attack">Sneak Attack</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_defender" value="Legendary Defender">
|
||||
<label for="cantrip_legendary_defender">Defender</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_recklessness" value="Legendary Recklessness Prowess">
|
||||
<label for="cantrip_legendary_recklessness">Recklessness</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_shield" value="Legendary Shield Aptitude">
|
||||
<label for="cantrip_legendary_shield">Shield</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_dual_wield" value="Legendary Dual Wield Aptitude">
|
||||
<label for="cantrip_legendary_dual_wield">Dual Wield</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_dirty_fighting" value="Legendary Dirty Fighting Prowess">
|
||||
<label for="cantrip_legendary_dirty_fighting">Dirty Fighting</label>
|
||||
</div>
|
||||
|
||||
<!-- Magic/Utility Skills -->
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_summoning" value="Legendary Summoning Prowess">
|
||||
<label for="cantrip_legendary_summoning">Summoning</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_healing" value="Legendary Healing Prowess">
|
||||
<label for="cantrip_legendary_healing">Healing</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_arcane" value="Legendary Arcane Prowess">
|
||||
<label for="cantrip_legendary_arcane">Arcane</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_tinkering" value="Legendary Magic Item Tinkering Expertise">
|
||||
<label for="cantrip_legendary_tinkering">Tinkering</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_mana_conversion" value="Legendary Mana Conversion Prowess">
|
||||
<label for="cantrip_legendary_mana_conversion">Mana Convert</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_leadership" value="Legendary Leadership">
|
||||
<label for="cantrip_legendary_leadership">Leadership</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_deception" value="Legendary Deception Prowess">
|
||||
<label for="cantrip_legendary_deception">Deception</label>
|
||||
</div>
|
||||
|
||||
<!-- Defensive Spells -->
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_impenetrability" value="Legendary Impenetrability">
|
||||
<label for="cantrip_legendary_impenetrability">Impenetrability</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_impregnability" value="Legendary Impregnability">
|
||||
<label for="cantrip_legendary_impregnability">Impregnability</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_invulnerability" value="Legendary Invulnerability">
|
||||
<label for="cantrip_legendary_invulnerability">Invulnerability</label>
|
||||
</div>
|
||||
|
||||
<!-- Specialized/Rare -->
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_hermetic_link" value="Legendary Hermetic Link">
|
||||
<label for="cantrip_legendary_hermetic_link">Hermetic Link</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_person_attunement" value="Legendary Person Attunement">
|
||||
<label for="cantrip_legendary_person_attunement">Person Attune</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_spirit_thirst" value="Legendary Spirit Thirst">
|
||||
<label for="cantrip_legendary_spirit_thirst">Spirit Thirst</label>
|
||||
</div>
|
||||
|
||||
<!-- Bane Spells -->
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_piercing_bane" value="Legendary Piercing Bane">
|
||||
<label for="cantrip_legendary_piercing_bane">Piercing Bane</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="cantrip_legendary_storm_bane" value="Legendary Storm Bane">
|
||||
<label for="cantrip_legendary_storm_bane">Storm Bane</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -636,6 +823,77 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Equipment Slots -->
|
||||
<div class="filter-section">
|
||||
<label class="section-label">Equipment Slots:</label>
|
||||
|
||||
<!-- Armor Slots -->
|
||||
<div class="checkbox-container" id="armor-slots">
|
||||
<label class="subsection-label">Armor:</label>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_head" value="Head">
|
||||
<label for="slot_head">Head</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_chest" value="Chest">
|
||||
<label for="slot_chest">Chest</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_abdomen" value="Abdomen">
|
||||
<label for="slot_abdomen">Abdomen</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_upper_arms" value="Upper Arms">
|
||||
<label for="slot_upper_arms">Upper Arms</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_lower_arms" value="Lower Arms">
|
||||
<label for="slot_lower_arms">Lower Arms</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_hands" value="Hands">
|
||||
<label for="slot_hands">Hands</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_upper_legs" value="Upper Legs">
|
||||
<label for="slot_upper_legs">Upper Legs</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_lower_legs" value="Lower Legs">
|
||||
<label for="slot_lower_legs">Lower Legs</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_feet" value="Feet">
|
||||
<label for="slot_feet">Feet</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_shield" value="Shield">
|
||||
<label for="slot_shield">Shield</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Jewelry Slots -->
|
||||
<div class="checkbox-container" id="jewelry-slots">
|
||||
<label class="subsection-label">Jewelry:</label>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_neck" value="Neck">
|
||||
<label for="slot_neck">Neck</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_ring" value="Ring">
|
||||
<label for="slot_ring">Ring</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_bracelet" value="Bracelet">
|
||||
<label for="slot_bracelet">Bracelet</label>
|
||||
</div>
|
||||
<div class="checkbox-item">
|
||||
<input type="checkbox" id="slot_trinket" value="Trinket">
|
||||
<label for="slot_trinket">Trinket</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-actions">
|
||||
<button type="button" class="btn btn-secondary" id="clearBtn">Clear All</button>
|
||||
<button type="submit" class="btn btn-primary">Search Items</button>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1989,4 +1989,12 @@ function openQuestStatus() {
|
|||
window.open('/quest-status.html', '_blank');
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the Player Dashboard interface in a new browser tab.
|
||||
*/
|
||||
function openPlayerDashboard() {
|
||||
// Open the Player Dashboard page in a new tab
|
||||
window.open('/player-dashboard.html', '_blank');
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1460,6 +1460,34 @@ body.noselect, body.noselect * {
|
|||
margin: -2px -4px;
|
||||
}
|
||||
|
||||
.player-dashboard-link {
|
||||
margin: 0 0 12px;
|
||||
padding: 8px 12px;
|
||||
background: var(--card);
|
||||
border: 1px solid #88f;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.player-dashboard-link a {
|
||||
color: #88f;
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.player-dashboard-link a:hover {
|
||||
color: #fff;
|
||||
background: rgba(136, 136, 255, 0.1);
|
||||
border-radius: 2px;
|
||||
padding: 2px 4px;
|
||||
margin: -2px -4px;
|
||||
}
|
||||
|
||||
/* Sortable column styles for inventory tables */
|
||||
.sortable {
|
||||
cursor: pointer;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue