hensei-web/src/lib/features/database/summons/sections/SummonTaxonomySection.svelte

94 lines
2.9 KiB
Svelte

<svelte:options runes={true} />
<script lang="ts">
import { createQuery } from '@tanstack/svelte-query'
import type { SummonSuggestions } from '$lib/api/adapters/entity.adapter'
import { entityQueries } from '$lib/api/queries/entity.queries'
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
import DetailItem from '$lib/components/ui/DetailItem.svelte'
import SuggestionDetailItem from '$lib/components/ui/SuggestionDetailItem.svelte'
import ElementLabel from '$lib/components/labels/ElementLabel.svelte'
import { getElementLabel, getElementOptions } from '$lib/utils/element'
import type { SummonSeriesRef } from '$lib/types/api/summonSeries'
type ElementName = 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light'
interface Props {
summon: any
editMode?: boolean
editData?: any
// Suggestion support for batch import
suggestions?: SummonSuggestions
dismissedSuggestions?: Set<string>
onAcceptSuggestion?: (field: string, value: any) => void
onDismissSuggestion?: (field: string) => void
}
let {
summon,
editMode = false,
editData = $bindable(),
suggestions,
dismissedSuggestions,
onAcceptSuggestion,
onDismissSuggestion
}: Props = $props()
// Fetch summon series list from API
const summonSeriesQuery = createQuery(() => entityQueries.summonSeriesList())
const elementOptions = getElementOptions()
// Build series options from fetched data
const seriesOptions = $derived.by(() => {
const series = summonSeriesQuery.data ?? []
return [
{ value: '', label: 'None' },
...series.map((s) => ({
value: s.id,
label: s.name.en
}))
]
})
// Get element name for checkbox theming
const elementName = $derived.by((): ElementName | undefined => {
const el = editMode ? editData?.element : summon?.element
const label = getElementLabel(el)
return label !== '—' && label !== 'Null' ? (label.toLowerCase() as ElementName) : undefined
})
// Format series label for display mode
function formatSeriesLabel(series: SummonSeriesRef | null | undefined): string {
if (!series) return '—'
return series.name?.en || '—'
}
</script>
<DetailsContainer title="Details">
{#if editMode}
<SuggestionDetailItem
label="Element"
bind:value={editData.element}
editable={true}
type="select"
options={elementOptions}
suggestion={suggestions?.element}
dismissedSuggestion={dismissedSuggestions?.has('element')}
onAcceptSuggestion={() => onAcceptSuggestion?.('element', suggestions?.element)}
onDismissSuggestion={() => onDismissSuggestion?.('element')}
/>
<DetailItem
label="Series"
bind:value={editData.series}
editable={true}
type="select"
options={seriesOptions}
/>
{:else}
<DetailItem label="Element">
<ElementLabel element={summon.element} size="medium" />
</DetailItem>
<DetailItem label="Series" value={formatSeriesLabel(summon.series)} />
{/if}
</DetailsContainer>