Add client-side spell column sorting and improve inventory search
- Implement client-side sorting for all columns including spell_names - Add computed_spell_names CTE for server-side sort fallback - Add resizable columns with localStorage persistence - Add Cloak slot detection by name pattern - Increase items limit to 50000 for full inventory loading - Increase proxy timeout to 60s for large queries - Remove pagination (all items loaded at once for sorting) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
25980edf99
commit
8cae94d87d
6 changed files with 294 additions and 111 deletions
|
|
@ -2085,7 +2085,7 @@ async def search_items(
|
|||
sort_by: str = Query("name", description="Sort field: name, value, damage, armor, workmanship, damage_rating, crit_damage_rating, level"),
|
||||
sort_dir: str = Query("asc", description="Sort direction: asc or desc"),
|
||||
page: int = Query(1, ge=1, description="Page number"),
|
||||
limit: int = Query(200, ge=1, le=10000, description="Items per page")
|
||||
limit: int = Query(200, ge=1, le=50000, description="Items per page")
|
||||
):
|
||||
"""
|
||||
Search items across characters with comprehensive filtering options.
|
||||
|
|
@ -2232,14 +2232,24 @@ async def search_items(
|
|||
WHEN i.object_class = 6 THEN 'Melee Weapon'
|
||||
WHEN i.object_class = 7 THEN 'Missile Weapon'
|
||||
WHEN i.object_class = 8 THEN 'Held'
|
||||
|
||||
|
||||
-- Check wielded location for two-handed weapons
|
||||
WHEN i.current_wielded_location = 67108864 THEN 'Two-Handed'
|
||||
|
||||
|
||||
-- CLOAKS: Identify by name pattern
|
||||
WHEN i.name ILIKE '%cloak%' THEN 'Cloak'
|
||||
|
||||
-- DEFAULT
|
||||
ELSE '-'
|
||||
END as computed_slot_name
|
||||
|
||||
END as computed_slot_name,
|
||||
|
||||
-- Compute spell_names (spell IDs for client-side name lookup)
|
||||
COALESCE(
|
||||
(SELECT STRING_AGG(CAST(sp_inner.spell_id AS VARCHAR), ',' ORDER BY sp_inner.spell_id)
|
||||
FROM item_spells sp_inner WHERE sp_inner.item_id = i.id),
|
||||
''
|
||||
) as computed_spell_names
|
||||
|
||||
FROM items i
|
||||
LEFT JOIN item_combat_stats cs ON i.id = cs.item_id
|
||||
LEFT JOIN item_requirements req ON i.id = req.item_id
|
||||
|
|
@ -2495,7 +2505,11 @@ async def search_items(
|
|||
slot_approaches.append("(object_class = 11 AND name ILIKE '%trinket%')")
|
||||
# 4. Jewelry fallback: items that don't match other jewelry patterns
|
||||
slot_approaches.append("(object_class = 4 AND name NOT ILIKE '%ring%' AND name NOT ILIKE '%bracelet%' AND name NOT ILIKE '%amulet%' AND name NOT ILIKE '%necklace%' AND name NOT ILIKE '%gorget%')")
|
||||
|
||||
elif slot_name.lower() == 'cloak':
|
||||
# For cloaks: identify by name pattern
|
||||
slot_approaches.append("(name ILIKE '%cloak%')")
|
||||
slot_approaches.append("(computed_slot_name = 'Cloak')")
|
||||
|
||||
# Combine approaches with OR (any approach can match)
|
||||
if slot_approaches:
|
||||
slot_conditions.append(f"({' OR '.join(slot_approaches)})")
|
||||
|
|
@ -2663,9 +2677,11 @@ async def search_items(
|
|||
# Add ORDER BY
|
||||
sort_mapping = {
|
||||
"name": "name",
|
||||
"character_name": "character_name",
|
||||
"value": "value",
|
||||
"damage": "max_damage",
|
||||
"armor": "armor_level",
|
||||
"armor": "armor_level",
|
||||
"armor_level": "armor_level",
|
||||
"workmanship": "workmanship",
|
||||
"level": "wield_level",
|
||||
"damage_rating": "damage_rating",
|
||||
|
|
@ -2673,11 +2689,20 @@ async def search_items(
|
|||
"heal_boost_rating": "heal_boost_rating",
|
||||
"vitality_rating": "vitality_rating",
|
||||
"damage_resist_rating": "damage_resist_rating",
|
||||
"crit_damage_resist_rating": "crit_damage_resist_rating"
|
||||
"crit_damage_resist_rating": "crit_damage_resist_rating",
|
||||
"item_set": "item_set",
|
||||
"slot_name": "computed_slot_name",
|
||||
"coverage": "coverage_mask",
|
||||
"item_type_name": "object_class",
|
||||
"last_updated": "timestamp",
|
||||
"spell_names": "computed_spell_names"
|
||||
}
|
||||
sort_field = sort_mapping.get(sort_by, "name")
|
||||
sort_direction = "DESC" if sort_dir.lower() == "desc" else "ASC"
|
||||
query_parts.append(f"ORDER BY {sort_field} {sort_direction}")
|
||||
|
||||
# Handle NULLS for optional fields
|
||||
nulls_clause = "NULLS LAST" if sort_direction == "ASC" else "NULLS FIRST"
|
||||
query_parts.append(f"ORDER BY {sort_field} {sort_direction} {nulls_clause}")
|
||||
|
||||
# Add pagination
|
||||
offset = (page - 1) * limit
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue