fetch weapon series from API in collection filters
This commit is contained in:
parent
a251240331
commit
139e602808
4 changed files with 54 additions and 22 deletions
|
|
@ -45,7 +45,7 @@
|
||||||
let elementFilters = $state<number[]>([])
|
let elementFilters = $state<number[]>([])
|
||||||
let rarityFilters = $state<number[]>([])
|
let rarityFilters = $state<number[]>([])
|
||||||
let seasonFilters = $state<number[]>([])
|
let seasonFilters = $state<number[]>([])
|
||||||
let seriesFilters = $state<number[]>([])
|
let seriesFilters = $state<(number | string)[]>([])
|
||||||
let raceFilters = $state<number[]>([])
|
let raceFilters = $state<number[]>([])
|
||||||
let proficiencyFilters = $state<number[]>([])
|
let proficiencyFilters = $state<number[]>([])
|
||||||
let genderFilters = $state<number[]>([])
|
let genderFilters = $state<number[]>([])
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
import MultiSelect from '$lib/components/ui/MultiSelect.svelte'
|
import MultiSelect from '$lib/components/ui/MultiSelect.svelte'
|
||||||
import Select from '$lib/components/ui/Select.svelte'
|
import Select from '$lib/components/ui/Select.svelte'
|
||||||
import Icon from '$lib/components/Icon.svelte'
|
import Icon from '$lib/components/Icon.svelte'
|
||||||
|
import { createQuery, queryOptions } from '@tanstack/svelte-query'
|
||||||
|
import { entityAdapter } from '$lib/api/adapters/entity.adapter'
|
||||||
|
|
||||||
type EntityType = 'character' | 'weapon' | 'summon'
|
type EntityType = 'character' | 'weapon' | 'summon'
|
||||||
|
|
||||||
|
|
@ -16,7 +18,8 @@
|
||||||
elementFilters?: number[]
|
elementFilters?: number[]
|
||||||
rarityFilters?: number[]
|
rarityFilters?: number[]
|
||||||
seasonFilters?: number[]
|
seasonFilters?: number[]
|
||||||
seriesFilters?: number[]
|
/** Series filters - number[] for characters, string[] for weapons (UUIDs) */
|
||||||
|
seriesFilters?: (number | string)[]
|
||||||
raceFilters?: number[]
|
raceFilters?: number[]
|
||||||
proficiencyFilters?: number[]
|
proficiencyFilters?: number[]
|
||||||
genderFilters?: number[]
|
genderFilters?: number[]
|
||||||
|
|
@ -47,7 +50,8 @@
|
||||||
element: number[]
|
element: number[]
|
||||||
rarity: number[]
|
rarity: number[]
|
||||||
season: number[]
|
season: number[]
|
||||||
series: number[]
|
/** Series filters - number[] for characters, string[] for weapons (UUIDs) */
|
||||||
|
series: (number | string)[]
|
||||||
race: number[]
|
race: number[]
|
||||||
proficiency: number[]
|
proficiency: number[]
|
||||||
gender: number[]
|
gender: number[]
|
||||||
|
|
@ -149,17 +153,44 @@
|
||||||
{ value: 10, label: 'Katana' }
|
{ value: 10, label: 'Katana' }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Fetch weapon series from API (only when entityType is weapon)
|
||||||
|
const weaponSeriesQuery = createQuery(() =>
|
||||||
|
queryOptions({
|
||||||
|
queryKey: ['weaponSeries', 'list'] as const,
|
||||||
|
queryFn: () => entityAdapter.getWeaponSeriesList(),
|
||||||
|
enabled: entityType === 'weapon',
|
||||||
|
staleTime: 1000 * 60 * 60, // 1 hour
|
||||||
|
gcTime: 1000 * 60 * 60 * 24 // 24 hours
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
// Convert record maps to arrays for iteration
|
// Convert record maps to arrays for iteration
|
||||||
const seasons = Object.entries(CHARACTER_SEASON_NAMES).map(([value, label]) => ({
|
const seasons = Object.entries(CHARACTER_SEASON_NAMES).map(([value, label]) => ({
|
||||||
value: Number(value),
|
value: Number(value),
|
||||||
label
|
label
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const series = Object.entries(CHARACTER_SERIES_NAMES).map(([value, label]) => ({
|
// Character series (hardcoded enum)
|
||||||
|
const characterSeries = Object.entries(CHARACTER_SERIES_NAMES).map(([value, label]) => ({
|
||||||
value: Number(value),
|
value: Number(value),
|
||||||
label
|
label
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// Build series options based on entity type
|
||||||
|
// For weapons: use API-fetched series with string IDs
|
||||||
|
// For characters: use hardcoded enum with number values
|
||||||
|
const seriesOptions = $derived.by(() => {
|
||||||
|
if (entityType === 'weapon' && weaponSeriesQuery.data) {
|
||||||
|
return weaponSeriesQuery.data
|
||||||
|
.sort((a, b) => a.order - b.order)
|
||||||
|
.map((s) => ({
|
||||||
|
value: s.id,
|
||||||
|
label: s.name.en
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return characterSeries
|
||||||
|
})
|
||||||
|
|
||||||
const races = Object.entries(RACE_LABELS)
|
const races = Object.entries(RACE_LABELS)
|
||||||
.filter(([value]) => Number(value) !== 0) // Exclude Unknown
|
.filter(([value]) => Number(value) !== 0) // Exclude Unknown
|
||||||
.map(([value, label]) => ({
|
.map(([value, label]) => ({
|
||||||
|
|
@ -201,7 +232,7 @@
|
||||||
emitChange()
|
emitChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSeriesChange(value: number[]) {
|
function handleSeriesChange(value: (number | string)[]) {
|
||||||
seriesFilters = value
|
seriesFilters = value
|
||||||
emitChange()
|
emitChange()
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +312,7 @@
|
||||||
|
|
||||||
{#if effectiveShowFilters.series}
|
{#if effectiveShowFilters.series}
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
options={series}
|
options={seriesOptions}
|
||||||
bind:value={seriesFilters}
|
bind:value={seriesFilters}
|
||||||
onValueChange={handleSeriesChange}
|
onValueChange={handleSeriesChange}
|
||||||
placeholder={entityType === 'weapon' ? 'Weapon Series' : 'Series'}
|
placeholder={entityType === 'weapon' ? 'Weapon Series' : 'Series'}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
import Button from '$lib/components/ui/Button.svelte'
|
import Button from '$lib/components/ui/Button.svelte'
|
||||||
import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte'
|
import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte'
|
||||||
import { getElementIcon } from '$lib/utils/images'
|
import { getElementIcon } from '$lib/utils/images'
|
||||||
|
import { seriesHasWeaponKeys, getSeriesSlug } from '$lib/utils/weaponSeries'
|
||||||
|
|
||||||
export interface WeaponEditValues {
|
export interface WeaponEditValues {
|
||||||
uncapLevel: number
|
uncapLevel: number
|
||||||
|
|
@ -106,21 +107,21 @@
|
||||||
|
|
||||||
// Derived conditions
|
// Derived conditions
|
||||||
const canChangeElement = $derived(weaponData?.element === 0)
|
const canChangeElement = $derived(weaponData?.element === 0)
|
||||||
const series = $derived(weaponData?.series ?? 0)
|
const series = $derived(weaponData?.series)
|
||||||
|
const seriesSlug = $derived(getSeriesSlug(series))
|
||||||
|
|
||||||
// Weapon key config keyed by WEAPON series
|
// Weapon key slot configuration by series slug
|
||||||
const WEAPON_KEY_SERIES: Record<number, { name: string; slots: number; keySeries: number }> = {
|
const WEAPON_KEY_SLOTS: Record<string, number> = {
|
||||||
2: { name: 'Dark Opus', slots: 2, keySeries: 3 },
|
'dark-opus': 2,
|
||||||
3: { name: 'Ultima', slots: 3, keySeries: 13 },
|
'ultima': 3,
|
||||||
17: { name: 'Draconic', slots: 2, keySeries: 27 },
|
'draconic': 2,
|
||||||
22: { name: 'Astral', slots: 1, keySeries: 19 },
|
'draconic-providence': 2,
|
||||||
34: { name: 'Superlative', slots: 2, keySeries: 40 }
|
'superlative': 2
|
||||||
}
|
}
|
||||||
|
|
||||||
const weaponKeyConfig = $derived(WEAPON_KEY_SERIES[series])
|
// Check if series has weapon keys using the utility (handles both formats)
|
||||||
const hasWeaponKeys = $derived(!!weaponKeyConfig)
|
const hasWeaponKeys = $derived(seriesHasWeaponKeys(series))
|
||||||
const keySlotCount = $derived(weaponKeyConfig?.slots ?? 0)
|
const keySlotCount = $derived(seriesSlug ? (WEAPON_KEY_SLOTS[seriesSlug] ?? 2) : 0)
|
||||||
const keySeries = $derived(weaponKeyConfig?.keySeries ?? 0)
|
|
||||||
|
|
||||||
const hasAxSkills = $derived(weaponData?.ax === true)
|
const hasAxSkills = $derived(weaponData?.ax === true)
|
||||||
const axType = $derived(weaponData?.axType ?? 1)
|
const axType = $derived(weaponData?.axType ?? 1)
|
||||||
|
|
@ -272,7 +273,7 @@
|
||||||
<div class="section-content key-selects">
|
<div class="section-content key-selects">
|
||||||
{#if keySlotCount >= 1}
|
{#if keySlotCount >= 1}
|
||||||
<WeaponKeySelect
|
<WeaponKeySelect
|
||||||
series={keySeries}
|
{seriesSlug}
|
||||||
slot={0}
|
slot={0}
|
||||||
bind:value={weaponKey1}
|
bind:value={weaponKey1}
|
||||||
{transcendenceStep}
|
{transcendenceStep}
|
||||||
|
|
@ -280,7 +281,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
{#if keySlotCount >= 2}
|
{#if keySlotCount >= 2}
|
||||||
<WeaponKeySelect
|
<WeaponKeySelect
|
||||||
series={keySeries}
|
{seriesSlug}
|
||||||
slot={1}
|
slot={1}
|
||||||
bind:value={weaponKey2}
|
bind:value={weaponKey2}
|
||||||
{transcendenceStep}
|
{transcendenceStep}
|
||||||
|
|
@ -288,7 +289,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
{#if keySlotCount >= 3}
|
{#if keySlotCount >= 3}
|
||||||
<WeaponKeySelect
|
<WeaponKeySelect
|
||||||
series={keySeries}
|
{seriesSlug}
|
||||||
slot={2}
|
slot={2}
|
||||||
bind:value={weaponKey3}
|
bind:value={weaponKey3}
|
||||||
{transcendenceStep}
|
{transcendenceStep}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
let elementFilters = $state<number[]>([])
|
let elementFilters = $state<number[]>([])
|
||||||
let rarityFilters = $state<number[]>([])
|
let rarityFilters = $state<number[]>([])
|
||||||
let proficiencyFilters = $state<number[]>([])
|
let proficiencyFilters = $state<number[]>([])
|
||||||
let seriesFilters = $state<number[]>([])
|
let seriesFilters = $state<(number | string)[]>([])
|
||||||
|
|
||||||
// Sort state
|
// Sort state
|
||||||
let sortBy = $state<CollectionSortKey>('name_asc')
|
let sortBy = $state<CollectionSortKey>('name_asc')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue