Merge svelte-main into feature/remove-suggestion-ui-v2

Resolve conflicts in import pages by removing redundant Basic Info
sections since MetadataSection components now handle name fields.
This commit is contained in:
Justin Edmund 2026-01-04 14:41:00 -08:00
commit 5fcba24cdd
7 changed files with 105 additions and 74 deletions

View file

@ -67,19 +67,27 @@
<DetailsContainer title="Metadata"> <DetailsContainer title="Metadata">
{#if editMode} {#if editMode}
<DetailItem <SuggestionDetailItem
label="Name (EN)" label="Name (EN)"
bind:value={editData.name} bind:value={editData.name}
editable={true} editable={true}
type="text" type="text"
placeholder="English name" placeholder="English name"
suggestion={suggestions?.nameEn}
dismissedSuggestion={dismissedSuggestions?.has('name')}
onAcceptSuggestion={() => onAcceptSuggestion?.('name', suggestions?.nameEn)}
onDismissSuggestion={() => onDismissSuggestion?.('name')}
/> />
<DetailItem <SuggestionDetailItem
label="Name (JP)" label="Name (JP)"
bind:value={editData.nameJp} bind:value={editData.nameJp}
editable={true} editable={true}
type="text" type="text"
placeholder="日本語名" placeholder="日本語名"
suggestion={suggestions?.nameJp}
dismissedSuggestion={dismissedSuggestions?.has('nameJp')}
onAcceptSuggestion={() => onAcceptSuggestion?.('nameJp', suggestions?.nameJp)}
onDismissSuggestion={() => onDismissSuggestion?.('nameJp')}
/> />
<DetailItem <DetailItem
label="Rarity" label="Rarity"
@ -88,12 +96,16 @@
type="select" type="select"
options={rarityOptions} options={rarityOptions}
/> />
<DetailItem <SuggestionDetailItem
label="Granblue ID" label="Granblue ID"
bind:value={editData.granblueId} bind:value={editData.granblueId}
editable={true} editable={true}
type="text" type="text"
placeholder="Granblue ID" placeholder="Granblue ID"
suggestion={suggestions?.granblueId}
dismissedSuggestion={dismissedSuggestions?.has('granblueId')}
onAcceptSuggestion={() => onAcceptSuggestion?.('granblueId', suggestions?.granblueId)}
onDismissSuggestion={() => onDismissSuggestion?.('granblueId')}
/> />
<DetailItem <DetailItem
label="Character ID" label="Character ID"

View file

@ -23,19 +23,27 @@
<DetailsContainer title="Metadata"> <DetailsContainer title="Metadata">
{#if editMode} {#if editMode}
<DetailItem <SuggestionDetailItem
label="Name (EN)" label="Name (EN)"
bind:value={editData.name} bind:value={editData.name}
editable={true} editable={true}
type="text" type="text"
placeholder="English name" placeholder="English name"
suggestion={suggestions?.nameEn}
dismissedSuggestion={dismissedSuggestions?.has('name')}
onAcceptSuggestion={() => onAcceptSuggestion?.('name', suggestions?.nameEn)}
onDismissSuggestion={() => onDismissSuggestion?.('name')}
/> />
<DetailItem <SuggestionDetailItem
label="Name (JP)" label="Name (JP)"
bind:value={editData.nameJp} bind:value={editData.nameJp}
editable={true} editable={true}
type="text" type="text"
placeholder="日本語名" placeholder="日本語名"
suggestion={suggestions?.nameJp}
dismissedSuggestion={dismissedSuggestions?.has('nameJp')}
onAcceptSuggestion={() => onAcceptSuggestion?.('nameJp', suggestions?.nameJp)}
onDismissSuggestion={() => onDismissSuggestion?.('nameJp')}
/> />
<DetailItem <DetailItem
label="Rarity" label="Rarity"
@ -50,6 +58,14 @@
editable={true} editable={true}
type="text" type="text"
/> />
<DetailItem
label="Summon ID"
sublabel="Internal game identifier (if known)"
bind:value={editData.summonId}
editable={true}
type="text"
placeholder="Optional"
/>
{:else} {:else}
<DetailItem label="Name (EN)" value={summon.name?.en || '—'} /> <DetailItem label="Name (EN)" value={summon.name?.en || '—'} />
<DetailItem label="Name (JP)" value={summon.name?.ja || '—'} /> <DetailItem label="Name (JP)" value={summon.name?.ja || '—'} />

View file

@ -23,19 +23,27 @@
<DetailsContainer title="Metadata"> <DetailsContainer title="Metadata">
{#if editMode} {#if editMode}
<DetailItem <SuggestionDetailItem
label="Name (EN)" label="Name (EN)"
bind:value={editData.name} bind:value={editData.name}
editable={true} editable={true}
type="text" type="text"
placeholder="English name" placeholder="English name"
suggestion={suggestions?.nameEn}
dismissedSuggestion={dismissedSuggestions?.has('name')}
onAcceptSuggestion={() => onAcceptSuggestion?.('name', suggestions?.nameEn)}
onDismissSuggestion={() => onDismissSuggestion?.('name')}
/> />
<DetailItem <SuggestionDetailItem
label="Name (JP)" label="Name (JP)"
bind:value={editData.nameJp} bind:value={editData.nameJp}
editable={true} editable={true}
type="text" type="text"
placeholder="日本語名" placeholder="日本語名"
suggestion={suggestions?.nameJp}
dismissedSuggestion={dismissedSuggestions?.has('nameJp')}
onAcceptSuggestion={() => onAcceptSuggestion?.('nameJp', suggestions?.nameJp)}
onDismissSuggestion={() => onDismissSuggestion?.('nameJp')}
/> />
<DetailItem <DetailItem
label="Rarity" label="Rarity"

View file

@ -8,6 +8,14 @@ export function getRarityLabel(rarity: number): string {
return RARITY_LABELS[rarity] || '—' return RARITY_LABELS[rarity] || '—'
} }
/**
* Get rarity prefix for URL generation (e.g., "SSR", "SR", "R")
* Returns empty string for unknown rarity values
*/
export function getRarityPrefix(rarity: number): string {
return RARITY_LABELS[rarity] || ''
}
export function getRarityOptions() { export function getRarityOptions() {
return Object.entries(RARITY_LABELS).map(([value, label]) => ({ return Object.entries(RARITY_LABELS).map(([value, label]) => ({
value: Number(value), value: Number(value),

View file

@ -13,6 +13,7 @@
buildGamewithUrl, buildGamewithUrl,
buildKamigameUrl buildKamigameUrl
} from '$lib/utils/external-links' } from '$lib/utils/external-links'
import { getRarityPrefix } from '$lib/utils/rarity'
// Components // Components
import CharacterUncapSection from '$lib/features/database/characters/sections/CharacterUncapSection.svelte' import CharacterUncapSection from '$lib/features/database/characters/sections/CharacterUncapSection.svelte'
@ -83,6 +84,23 @@
// Get selected entity data // Get selected entity data
const selectedEntity = $derived(selectedWikiPage ? entities.get(selectedWikiPage) : null) const selectedEntity = $derived(selectedWikiPage ? entities.get(selectedWikiPage) : null)
// Auto-generate wiki URLs when Name (JP) or Rarity changes
$effect(() => {
if (!selectedWikiPage) return
const formData = formDataByPage[selectedWikiPage]
if (!formData) return
const nameJp = formData.nameJp
const rarity = formData.rarity
if (nameJp) {
// Auto-generate wikiJa: "Name (JP) (SSR)"
formData.wikiJa = `${nameJp} (${getRarityPrefix(rarity)})`
// Auto-generate kamigame: "Name (JP)" for characters (no rarity prefix)
formData.kamigame = nameJp
}
})
// Entity tabs for TabbedEntitySelector // Entity tabs for TabbedEntitySelector
const entityTabs = $derived<EntityTab[]>( const entityTabs = $derived<EntityTab[]>(
Array.from(entities.entries()).map(([wikiPage, entity]) => ({ Array.from(entities.entries()).map(([wikiPage, entity]) => ({
@ -427,31 +445,6 @@
</div> </div>
{:else if selectedWikiPage && formDataByPage[selectedWikiPage]} {:else if selectedWikiPage && formDataByPage[selectedWikiPage]}
<section class="details"> <section class="details">
<!-- Basic Info: Name fields needed for import (not in MetadataSection) -->
<DetailsContainer title="Basic Info">
<DetailItem
label="Name (EN)"
bind:value={formDataByPage[selectedWikiPage].name}
editable={true}
type="text"
placeholder="Character name"
/>
<DetailItem
label="Name (JP)"
bind:value={formDataByPage[selectedWikiPage].nameJp}
editable={true}
type="text"
placeholder="キャラクター名"
/>
<DetailItem
label="Granblue ID"
bind:value={formDataByPage[selectedWikiPage].granblueId}
editable={true}
type="text"
placeholder="3040001000"
/>
</DetailsContainer>
<CharacterMetadataSection <CharacterMetadataSection
character={emptyCharacter} character={emptyCharacter}
editMode={true} editMode={true}

View file

@ -13,6 +13,7 @@
buildGamewithUrl, buildGamewithUrl,
buildKamigameUrl buildKamigameUrl
} from '$lib/utils/external-links' } from '$lib/utils/external-links'
import { getRarityPrefix } from '$lib/utils/rarity'
// Components // Components
import SummonUncapSection from '$lib/features/database/summons/sections/SummonUncapSection.svelte' import SummonUncapSection from '$lib/features/database/summons/sections/SummonUncapSection.svelte'
@ -82,6 +83,23 @@
// Get selected entity data // Get selected entity data
const selectedEntity = $derived(selectedWikiPage ? entities.get(selectedWikiPage) : null) const selectedEntity = $derived(selectedWikiPage ? entities.get(selectedWikiPage) : null)
// Auto-generate wiki URLs when Name (JP) or Rarity changes
$effect(() => {
if (!selectedWikiPage) return
const formData = formDataByPage[selectedWikiPage]
if (!formData) return
const nameJp = formData.nameJp
const rarity = formData.rarity
if (nameJp) {
// Auto-generate wikiJa: "Name (JP) (SSR)"
formData.wikiJa = `${nameJp} (${getRarityPrefix(rarity)})`
// Auto-generate kamigame: "SSRName (JP)" for summons
formData.kamigame = `${getRarityPrefix(rarity)}${nameJp}`
}
})
// Entity tabs for TabbedEntitySelector // Entity tabs for TabbedEntitySelector
const entityTabs = $derived<EntityTab[]>( const entityTabs = $derived<EntityTab[]>(
Array.from(entities.entries()).map(([wikiPage, entity]) => ({ Array.from(entities.entries()).map(([wikiPage, entity]) => ({
@ -406,31 +424,6 @@
</div> </div>
{:else if selectedWikiPage && formDataByPage[selectedWikiPage]} {:else if selectedWikiPage && formDataByPage[selectedWikiPage]}
<section class="details"> <section class="details">
<DetailsContainer title="Basic Info">
<DetailItem
label="Name (EN)"
bind:value={formDataByPage[selectedWikiPage].name}
editable={true}
type="text"
placeholder="Summon name"
/>
<DetailItem
label="Name (JP)"
bind:value={formDataByPage[selectedWikiPage].nameJp}
editable={true}
type="text"
placeholder="召喚石名"
/>
<DetailItem
label="Summon ID"
sublabel="Internal game identifier (if known)"
bind:value={formDataByPage[selectedWikiPage].summonId}
editable={true}
type="text"
placeholder="Optional"
/>
</DetailsContainer>
<SummonMetadataSection <SummonMetadataSection
summon={emptySummon} summon={emptySummon}
editMode={true} editMode={true}

View file

@ -13,6 +13,7 @@
buildGamewithUrl, buildGamewithUrl,
buildKamigameUrl buildKamigameUrl
} from '$lib/utils/external-links' } from '$lib/utils/external-links'
import { getRarityPrefix } from '$lib/utils/rarity'
// Components // Components
import WeaponUncapSection from '$lib/features/database/weapons/sections/WeaponUncapSection.svelte' import WeaponUncapSection from '$lib/features/database/weapons/sections/WeaponUncapSection.svelte'
@ -82,6 +83,23 @@
// Get selected entity data // Get selected entity data
const selectedEntity = $derived(selectedWikiPage ? entities.get(selectedWikiPage) : null) const selectedEntity = $derived(selectedWikiPage ? entities.get(selectedWikiPage) : null)
// Auto-generate wiki URLs when Name (JP) or Rarity changes
$effect(() => {
if (!selectedWikiPage) return
const formData = formDataByPage[selectedWikiPage]
if (!formData) return
const nameJp = formData.nameJp
const rarity = formData.rarity
if (nameJp) {
// Auto-generate wikiJa: "Name (JP) (SSR)"
formData.wikiJa = `${nameJp} (${getRarityPrefix(rarity)})`
// Auto-generate kamigame: "SSRName (JP)" for weapons
formData.kamigame = `${getRarityPrefix(rarity)}${nameJp}`
}
})
// Entity tabs for TabbedEntitySelector // Entity tabs for TabbedEntitySelector
const entityTabs = $derived<EntityTab[]>( const entityTabs = $derived<EntityTab[]>(
Array.from(entities.entries()).map(([wikiPage, entity]) => ({ Array.from(entities.entries()).map(([wikiPage, entity]) => ({
@ -420,23 +438,6 @@
</div> </div>
{:else if selectedWikiPage && formDataByPage[selectedWikiPage]} {:else if selectedWikiPage && formDataByPage[selectedWikiPage]}
<section class="details"> <section class="details">
<DetailsContainer title="Basic Info">
<DetailItem
label="Name (EN)"
bind:value={formDataByPage[selectedWikiPage].name}
editable={true}
type="text"
placeholder="Weapon name"
/>
<DetailItem
label="Name (JP)"
bind:value={formDataByPage[selectedWikiPage].nameJp}
editable={true}
type="text"
placeholder="武器名"
/>
</DetailsContainer>
<WeaponMetadataSection <WeaponMetadataSection
weapon={emptyWeapon} weapon={emptyWeapon}
editMode={true} editMode={true}