move Recruits and Promotions to Gacha section
This commit is contained in:
parent
850c5dd771
commit
cfb62447a0
3 changed files with 96 additions and 40 deletions
|
|
@ -0,0 +1,93 @@
|
||||||
|
<svelte:options runes={true} />
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import type { WeaponSuggestions } 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 CharacterTypeahead from '$lib/components/ui/CharacterTypeahead.svelte'
|
||||||
|
import { PROMOTION_NAMES, getPromotionNames } from '$lib/types/enums'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
weapon: any
|
||||||
|
editMode?: boolean
|
||||||
|
editData?: any
|
||||||
|
// Suggestion support for batch import
|
||||||
|
suggestions?: WeaponSuggestions
|
||||||
|
dismissedSuggestions?: Set<string>
|
||||||
|
onAcceptSuggestion?: (field: string, value: any) => void
|
||||||
|
onDismissSuggestion?: (field: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
weapon,
|
||||||
|
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(', ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format recruits for display
|
||||||
|
function formatRecruitsDisplay(recruits: any): string {
|
||||||
|
if (!recruits) return '—'
|
||||||
|
if (typeof recruits === 'string') return recruits
|
||||||
|
return recruits.name?.en || recruits.granblueId || '—'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we should show the section in view mode
|
||||||
|
const hasGachaData = $derived.by(() => {
|
||||||
|
if (editMode) return true
|
||||||
|
const hasPromotions = weapon?.promotions && weapon.promotions.length > 0
|
||||||
|
const hasRecruits = weapon?.recruits
|
||||||
|
return hasPromotions || hasRecruits
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if hasGachaData}
|
||||||
|
<DetailsContainer title="Gacha">
|
||||||
|
{#if editMode}
|
||||||
|
<DetailItem label="Promotions" sublabel="Gacha pools where this weapon appears" editable={true}>
|
||||||
|
<MultiSelect
|
||||||
|
size="medium"
|
||||||
|
options={promotionOptions}
|
||||||
|
bind:value={editData.promotions}
|
||||||
|
placeholder="Select promotions"
|
||||||
|
contained
|
||||||
|
/>
|
||||||
|
</DetailItem>
|
||||||
|
<DetailItem label="Recruits" sublabel="Character recruited by this weapon">
|
||||||
|
<CharacterTypeahead
|
||||||
|
bind:value={editData.recruits}
|
||||||
|
placeholder="Search for character..."
|
||||||
|
/>
|
||||||
|
</DetailItem>
|
||||||
|
{:else}
|
||||||
|
<DetailItem
|
||||||
|
label="Promotions"
|
||||||
|
sublabel="Gacha pools where this weapon appears"
|
||||||
|
value={formatPromotionsDisplay(weapon.promotions)}
|
||||||
|
/>
|
||||||
|
{#if weapon.recruits}
|
||||||
|
<DetailItem
|
||||||
|
label="Recruits"
|
||||||
|
sublabel="Character recruited by this weapon"
|
||||||
|
value={formatRecruitsDisplay(weapon.recruits)}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
</DetailsContainer>
|
||||||
|
{/if}
|
||||||
|
|
@ -7,14 +7,12 @@
|
||||||
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
||||||
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 MultiSelect from '$lib/components/ui/MultiSelect.svelte'
|
|
||||||
import ElementLabel from '$lib/components/labels/ElementLabel.svelte'
|
import ElementLabel from '$lib/components/labels/ElementLabel.svelte'
|
||||||
import ProficiencyLabel from '$lib/components/labels/ProficiencyLabel.svelte'
|
import ProficiencyLabel from '$lib/components/labels/ProficiencyLabel.svelte'
|
||||||
import { getElementLabel, getElementOptions } from '$lib/utils/element'
|
import { getElementLabel, getElementOptions } from '$lib/utils/element'
|
||||||
import { getProficiencyOptions } from '$lib/utils/proficiency'
|
import { getProficiencyOptions } from '$lib/utils/proficiency'
|
||||||
import { getSeriesDisplayName } from '$lib/utils/weaponSeries'
|
import { getSeriesDisplayName } from '$lib/utils/weaponSeries'
|
||||||
import { isWeaponSeriesRef, type WeaponSeriesRef } from '$lib/types/api/weaponSeries'
|
import type { WeaponSeriesRef } from '$lib/types/api/weaponSeries'
|
||||||
import { PROMOTION_NAMES, getPromotionNames } from '$lib/types/enums'
|
|
||||||
|
|
||||||
type ElementName = 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light'
|
type ElementName = 'wind' | 'fire' | 'water' | 'earth' | 'dark' | 'light'
|
||||||
|
|
||||||
|
|
@ -58,12 +56,6 @@
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
// Promotion options for multiselect
|
|
||||||
const promotionOptions = Object.entries(PROMOTION_NAMES).map(([value, label]) => ({
|
|
||||||
value: Number(value),
|
|
||||||
label
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Get element name for checkbox theming
|
// Get element name for checkbox theming
|
||||||
const elementName = $derived.by((): ElementName | undefined => {
|
const elementName = $derived.by((): ElementName | undefined => {
|
||||||
const el = editMode ? editData.element : weapon?.element
|
const el = editMode ? editData.element : weapon?.element
|
||||||
|
|
@ -76,12 +68,6 @@
|
||||||
if (!series) return '—'
|
if (!series) return '—'
|
||||||
return getSeriesDisplayName(series, 'en') || '—'
|
return getSeriesDisplayName(series, 'en') || '—'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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">
|
||||||
|
|
@ -139,15 +125,6 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
element={elementName}
|
element={elementName}
|
||||||
/>
|
/>
|
||||||
<DetailItem label="Promotions" sublabel="Gacha pools where this weapon appears" editable={true}>
|
|
||||||
<MultiSelect
|
|
||||||
size="medium"
|
|
||||||
options={promotionOptions}
|
|
||||||
bind:value={editData.promotions}
|
|
||||||
placeholder="Select promotions"
|
|
||||||
contained
|
|
||||||
/>
|
|
||||||
</DetailItem>
|
|
||||||
{:else}
|
{:else}
|
||||||
<DetailItem label="Element">
|
<DetailItem label="Element">
|
||||||
<ElementLabel element={weapon.element} size="medium" />
|
<ElementLabel element={weapon.element} size="medium" />
|
||||||
|
|
@ -170,10 +147,5 @@
|
||||||
value={weapon.limit ? 'Yes' : 'No'}
|
value={weapon.limit ? 'Yes' : 'No'}
|
||||||
/>
|
/>
|
||||||
<DetailItem label="AX Skills" sublabel="Can have AX Skills" value={weapon.ax ? 'Yes' : 'No'} />
|
<DetailItem label="AX Skills" sublabel="Can have AX Skills" value={weapon.ax ? 'Yes' : 'No'} />
|
||||||
<DetailItem
|
|
||||||
label="Promotions"
|
|
||||||
sublabel="Gacha pools where this weapon appears"
|
|
||||||
value={formatPromotionsDisplay(weapon.promotions)}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
</DetailsContainer>
|
</DetailsContainer>
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
import WeaponUncapSection from '$lib/features/database/weapons/sections/WeaponUncapSection.svelte'
|
import WeaponUncapSection from '$lib/features/database/weapons/sections/WeaponUncapSection.svelte'
|
||||||
import WeaponTaxonomySection from '$lib/features/database/weapons/sections/WeaponTaxonomySection.svelte'
|
import WeaponTaxonomySection from '$lib/features/database/weapons/sections/WeaponTaxonomySection.svelte'
|
||||||
import WeaponStatsSection from '$lib/features/database/weapons/sections/WeaponStatsSection.svelte'
|
import WeaponStatsSection from '$lib/features/database/weapons/sections/WeaponStatsSection.svelte'
|
||||||
|
import WeaponGachaSection from '$lib/features/database/weapons/sections/WeaponGachaSection.svelte'
|
||||||
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
import DetailsContainer from '$lib/components/ui/DetailsContainer.svelte'
|
||||||
import DetailItem from '$lib/components/ui/DetailItem.svelte'
|
import DetailItem from '$lib/components/ui/DetailItem.svelte'
|
||||||
import TagInput from '$lib/components/ui/TagInput.svelte'
|
import TagInput from '$lib/components/ui/TagInput.svelte'
|
||||||
|
|
@ -218,6 +219,7 @@
|
||||||
<WeaponUncapSection {weapon} {editMode} bind:editData />
|
<WeaponUncapSection {weapon} {editMode} bind:editData />
|
||||||
<WeaponTaxonomySection {weapon} {editMode} bind:editData />
|
<WeaponTaxonomySection {weapon} {editMode} bind:editData />
|
||||||
<WeaponStatsSection {weapon} {editMode} bind:editData />
|
<WeaponStatsSection {weapon} {editMode} bind:editData />
|
||||||
|
<WeaponGachaSection {weapon} {editMode} bind:editData />
|
||||||
|
|
||||||
<DetailsContainer title="Nicknames">
|
<DetailsContainer title="Nicknames">
|
||||||
<DetailItem label="Nicknames (EN)">
|
<DetailItem label="Nicknames (EN)">
|
||||||
|
|
@ -299,17 +301,6 @@
|
||||||
width="480px"
|
width="480px"
|
||||||
/>
|
/>
|
||||||
</DetailsContainer>
|
</DetailsContainer>
|
||||||
|
|
||||||
<DetailsContainer title="Character">
|
|
||||||
<DetailItem
|
|
||||||
label="Recruits"
|
|
||||||
sublabel="Character ID this weapon recruits"
|
|
||||||
bind:value={editData.recruits}
|
|
||||||
editable={true}
|
|
||||||
type="text"
|
|
||||||
placeholder="Character ID..."
|
|
||||||
/>
|
|
||||||
</DetailsContainer>
|
|
||||||
</section>
|
</section>
|
||||||
</DetailScaffold>
|
</DetailScaffold>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue