add promotions to summon database views

This commit is contained in:
Justin Edmund 2025-12-02 05:25:56 -08:00
parent 8c45c21939
commit 23ae7f70ba
2 changed files with 44 additions and 8 deletions

View file

@ -5,6 +5,7 @@ export const SummonEditSchema = z.object({
granblue_id: z.string().min(1), granblue_id: z.string().min(1),
rarity: z.number().int().min(1), rarity: z.number().int().min(1),
element: z.number().int().min(0), element: z.number().int().min(0),
promotions: z.array(z.number().int().min(1)),
min_hp: z.number().int().min(0), min_hp: z.number().int().min(0),
max_hp: z.number().int().min(0), max_hp: z.number().int().min(0),
max_hp_flb: z.number().int().min(0), max_hp_flb: z.number().int().min(0),
@ -21,15 +22,17 @@ export type SummonEdit = z.infer<typeof SummonEditSchema>
export function toEditData(model: any): SummonEdit { export function toEditData(model: any): SummonEdit {
return { return {
name: model?.name ?? '', name: model?.name ?? '',
granblue_id: model?.granblue_id ?? '', granblue_id: model?.granblueId ?? model?.granblue_id ?? '',
rarity: model?.rarity ?? 1, rarity: model?.rarity ?? 1,
element: model?.element ?? 0, element: model?.element ?? 0,
min_hp: model?.hp?.min_hp ?? 0, promotions: model?.promotions ?? [],
max_hp: model?.hp?.max_hp ?? 0, // API returns camelCase after transformation
max_hp_flb: model?.hp?.max_hp_flb ?? 0, min_hp: model?.hp?.minHp ?? model?.hp?.min_hp ?? 0,
min_atk: model?.atk?.min_atk ?? 0, max_hp: model?.hp?.maxHp ?? model?.hp?.max_hp ?? 0,
max_atk: model?.atk?.max_atk ?? 0, max_hp_flb: model?.hp?.maxHpFlb ?? model?.hp?.max_hp_flb ?? 0,
max_atk_flb: model?.atk?.max_atk_flb ?? 0, min_atk: model?.atk?.minAtk ?? model?.atk?.min_atk ?? 0,
max_atk: model?.atk?.maxAtk ?? model?.atk?.max_atk ?? 0,
max_atk_flb: model?.atk?.maxAtkFlb ?? model?.atk?.max_atk_flb ?? 0,
flb: model?.uncap?.flb ?? false, flb: model?.uncap?.flb ?? false,
ulb: model?.uncap?.ulb ?? false, ulb: model?.uncap?.ulb ?? false,
transcendence: model?.uncap?.transcendence ?? false transcendence: model?.uncap?.transcendence ?? false
@ -42,6 +45,7 @@ export function toPayload(edit: SummonEdit) {
granblue_id: edit.granblue_id, granblue_id: edit.granblue_id,
rarity: edit.rarity, rarity: edit.rarity,
element: edit.element, element: edit.element,
promotions: edit.promotions,
hp: { hp: {
min_hp: edit.min_hp, min_hp: edit.min_hp,
max_hp: edit.max_hp, max_hp: edit.max_hp,

View file

@ -6,7 +6,10 @@
import DetailItem from '$lib/components/ui/DetailItem.svelte' import DetailItem from '$lib/components/ui/DetailItem.svelte'
import SuggestionDetailItem from '$lib/components/ui/SuggestionDetailItem.svelte' import SuggestionDetailItem from '$lib/components/ui/SuggestionDetailItem.svelte'
import ElementLabel from '$lib/components/labels/ElementLabel.svelte' import ElementLabel from '$lib/components/labels/ElementLabel.svelte'
import { getElementOptions } from '$lib/utils/element' import { getElementLabel, getElementOptions } from '$lib/utils/element'
import { PROMOTION_NAMES, getPromotionNames } from '$lib/types/enums'
type ElementName = 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light'
interface Props { interface Props {
summon: any summon: any
@ -30,6 +33,25 @@
}: Props = $props() }: Props = $props()
const elementOptions = getElementOptions() const elementOptions = getElementOptions()
// 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
const label = getElementLabel(el)
return label !== '—' && label !== 'Null' ? (label.toLowerCase() as ElementName) : undefined
})
// Format promotions for display
function formatPromotionsDisplay(promotions: number[]): string {
if (!promotions || promotions.length === 0) return '—'
return getPromotionNames(promotions).join(', ')
}
</script> </script>
<DetailsContainer title="Details"> <DetailsContainer title="Details">
@ -52,10 +74,20 @@
type="text" type="text"
placeholder="Series name" placeholder="Series name"
/> />
<DetailItem
label="Promotions"
sublabel="Gacha pools where this summon appears"
bind:value={editData.promotions}
editable={true}
type="multiselect"
options={promotionOptions}
element={elementName}
/>
{:else} {:else}
<DetailItem label="Element"> <DetailItem label="Element">
<ElementLabel element={summon.element} size="medium" /> <ElementLabel element={summon.element} size="medium" />
</DetailItem> </DetailItem>
<DetailItem label="Series" value={summon.series || '—'} /> <DetailItem label="Series" value={summon.series || '—'} />
<DetailItem label="Promotions" sublabel="Gacha pools where this summon appears" value={formatPromotionsDisplay(summon.promotions)} />
{/if} {/if}
</DetailsContainer> </DetailsContainer>