add Name fields to SummonMetadata, create SummonGachaSection, remove Promotions from Taxonomy

This commit is contained in:
Justin Edmund 2025-12-15 13:16:56 -08:00
parent a295175b36
commit 5ec31ade2d
3 changed files with 78 additions and 28 deletions

View file

@ -0,0 +1,62 @@
<svelte:options runes={true} />
<script lang="ts">
import type { SummonSuggestions } from '$lib/api/adapters/entity.adapter'
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
import DetailItem from '$lib/components/ui/DetailItem.svelte'
import MultiSelect from '$lib/components/ui/MultiSelect.svelte'
import { PROMOTION_NAMES, getPromotionNames } from '$lib/types/enums'
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()
// Promotion options for multiselect
const promotionOptions = Object.entries(PROMOTION_NAMES).map(([value, label]) => ({
value: Number(value),
label
}))
// Format promotions for display
function formatPromotionsDisplay(promotions: number[]): string {
if (!promotions || promotions.length === 0) return '—'
return getPromotionNames(promotions).join(', ')
}
</script>
<DetailsContainer title="Gacha">
{#if editMode}
<DetailItem label="Promotions" sublabel="Gacha pools where this summon appears" editable={true}>
<MultiSelect
size="medium"
options={promotionOptions}
bind:value={editData.promotions}
placeholder="Select promotions"
contained
/>
</DetailItem>
{:else}
<DetailItem
label="Promotions"
sublabel="Gacha pools where this summon appears"
value={formatPromotionsDisplay(summon.promotions)}
/>
{/if}
</DetailsContainer>

View file

@ -34,6 +34,20 @@
<DetailsContainer title="Metadata">
{#if editMode}
<DetailItem
label="Name (EN)"
bind:value={editData.name}
editable={true}
type="text"
placeholder="English name"
/>
<DetailItem
label="Name (JP)"
bind:value={editData.nameJp}
editable={true}
type="text"
placeholder="日本語名"
/>
<SuggestionDetailItem
label="Rarity"
bind:value={editData.rarity}
@ -52,6 +66,8 @@
type="text"
/>
{:else}
<DetailItem label="Name (EN)" value={summon.name?.en || '—'} />
<DetailItem label="Name (JP)" value={summon.name?.ja || '—'} />
<DetailItem label="Rarity" value={getRarityLabel(summon.rarity)} />
<DetailItem label="Granblue ID">
{#if summon.granblueId}

View file

@ -7,11 +7,9 @@
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 MultiSelect from '$lib/components/ui/MultiSelect.svelte'
import ElementLabel from '$lib/components/labels/ElementLabel.svelte'
import { getElementLabel, getElementOptions } from '$lib/utils/element'
import type { SummonSeriesRef } from '$lib/types/api/summonSeries'
import { PROMOTION_NAMES, getPromotionNames } from '$lib/types/enums'
type ElementName = 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light'
@ -53,12 +51,6 @@
]
})
// Promotion options for multiselect
const promotionOptions = Object.entries(PROMOTION_NAMES).map(([value, label]) => ({
value: Number(value),
label
}))
// Get element name for checkbox theming
const elementName = $derived.by((): ElementName | undefined => {
const el = editMode ? editData?.element : summon?.element
@ -71,12 +63,6 @@
if (!series) return '—'
return series.name?.en || '—'
}
// Format promotions for display
function formatPromotionsDisplay(promotions: number[]): string {
if (!promotions || promotions.length === 0) return '—'
return getPromotionNames(promotions).join(', ')
}
</script>
<DetailsContainer title="Details">
@ -99,24 +85,10 @@
type="select"
options={seriesOptions}
/>
<DetailItem label="Promotions" sublabel="Gacha pools where this summon appears" editable={true}>
<MultiSelect
size="medium"
options={promotionOptions}
bind:value={editData.promotions}
placeholder="Select promotions"
contained
/>
</DetailItem>
{:else}
<DetailItem label="Element">
<ElementLabel element={summon.element} size="medium" />
</DetailItem>
<DetailItem label="Series" value={formatSeriesLabel(summon.series)} />
<DetailItem
label="Promotions"
sublabel="Gacha pools where this summon appears"
value={formatPromotionsDisplay(summon.promotions)}
/>
{/if}
</DetailsContainer>