fix: type errors cleanup (161 -> 130 errors)
- Fix Party.svelte: add null checks for existingChar/existingWeapon/existingSummon - Fix DropdownItem.svelte: replace asChild with child snippet pattern for bits-ui v2 - Fix UncapStar.svelte, TranscendenceStar.svelte: tabIndex -> tabindex - Fix Party.svelte, Navigation.svelte: remove asChild prop usage - Fix images.ts: add | undefined to pose/element params for exactOptionalPropertyTypes - Fix ItemHeader.svelte, UncapIndicator.svelte: accept number | null | undefined - Fix GridRepCollection.svelte, GuidebookUnit.svelte: PartyView -> Party type - Fix search.adapter.ts: add optional type property to SearchResult - Update various Props interfaces for exactOptionalPropertyTypes compliance Co-Authored-By: Justin Edmund <justin@jedmund.com>
This commit is contained in:
parent
8178b8592f
commit
67eb624bfc
15 changed files with 118 additions and 96 deletions
|
|
@ -54,6 +54,8 @@ export interface SearchResult {
|
|||
series?: number
|
||||
/** URL for entity image */
|
||||
imageUrl?: string
|
||||
/** Type of entity (lowercase for compatibility) */
|
||||
type?: 'weapon' | 'character' | 'summon'
|
||||
/** Type of entity */
|
||||
searchableType: 'Weapon' | 'Character' | 'Summon'
|
||||
}
|
||||
|
|
@ -294,4 +296,4 @@ export class SearchAdapter extends BaseAdapter {
|
|||
* Default singleton instance for search operations
|
||||
* Use this for most search needs unless you need custom configuration
|
||||
*/
|
||||
export const searchAdapter = new SearchAdapter(DEFAULT_ADAPTER_CONFIG)
|
||||
export const searchAdapter = new SearchAdapter(DEFAULT_ADAPTER_CONFIG)
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@
|
|||
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content class="dropdown-content" sideOffset={5}>
|
||||
<DropdownItem asChild>
|
||||
<DropdownItem>
|
||||
<button onclick={() => (settingsModalOpen = true)}>
|
||||
{m.nav_settings()}
|
||||
</button>
|
||||
|
|
@ -201,7 +201,7 @@
|
|||
{/if}
|
||||
{#if isAuth}
|
||||
<DropdownMenu.Separator class="dropdown-separator" />
|
||||
<DropdownItem asChild>
|
||||
<DropdownItem>
|
||||
<button onclick={handleLogout}>{m.nav_logout()}</button>
|
||||
</DropdownItem>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import type { PartyView } from '$lib/api/schemas/party'
|
||||
import type { Party } from '$lib/types/api/party'
|
||||
|
||||
export let item: any | undefined
|
||||
export let position: number // 1..3
|
||||
|
||||
type PartyCtx = {
|
||||
getParty: () => PartyView
|
||||
updateParty: (p: PartyView) => void
|
||||
getParty: () => Party
|
||||
updateParty: (p: Party) => void
|
||||
canEdit: () => boolean
|
||||
services: { partyService: any }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
import DropZone from '$lib/components/dnd/DropZone.svelte'
|
||||
|
||||
interface Props {
|
||||
characters?: GridCharacter[]
|
||||
characters?: GridCharacter[] | undefined
|
||||
mainWeaponElement?: number | null | undefined
|
||||
partyElement?: number | null | undefined
|
||||
job?: Job
|
||||
container?: string
|
||||
job?: Job | undefined
|
||||
container?: string | undefined
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
|
|||
|
|
@ -13,16 +13,16 @@
|
|||
import Icon from '$lib/components/Icon.svelte'
|
||||
|
||||
interface Props {
|
||||
job?: Job
|
||||
jobSkills?: JobSkillList
|
||||
accessory?: JobAccessory
|
||||
canEdit?: boolean
|
||||
gender?: Gender
|
||||
element?: number
|
||||
onSelectJob?: () => void
|
||||
onSelectSkill?: (slot: number) => void
|
||||
onRemoveSkill?: (slot: number) => void
|
||||
onSelectAccessory?: () => void
|
||||
job?: Job | undefined
|
||||
jobSkills?: JobSkillList | undefined
|
||||
accessory?: JobAccessory | undefined
|
||||
canEdit?: boolean | undefined
|
||||
gender?: Gender | undefined
|
||||
element?: number | undefined
|
||||
onSelectJob?: (() => void) | undefined
|
||||
onSelectSkill?: ((slot: number) => void) | undefined
|
||||
onRemoveSkill?: ((slot: number) => void) | undefined
|
||||
onSelectAccessory?: (() => void) | undefined
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@
|
|||
try {
|
||||
// Update skills with the new skill in the slot
|
||||
const updatedSkills = { ...party.jobSkills }
|
||||
updatedSkills[slot as keyof typeof updatedSkills] = skill
|
||||
updatedSkills[String(slot) as keyof typeof updatedSkills] = skill
|
||||
|
||||
console.log('[Party] Current jobSkills:', party.jobSkills)
|
||||
console.log('[Party] Updated jobSkills object:', updatedSkills)
|
||||
|
|
@ -459,7 +459,7 @@
|
|||
try {
|
||||
// Remove skill from slot
|
||||
const updatedSkills = { ...party.jobSkills }
|
||||
delete updatedSkills[slot as keyof typeof updatedSkills]
|
||||
delete updatedSkills[String(slot) as keyof typeof updatedSkills]
|
||||
|
||||
console.log('[Party] Removing skill from slot:', slot)
|
||||
console.log('[Party] Current jobSkills:', party.jobSkills)
|
||||
|
|
@ -526,7 +526,7 @@
|
|||
try {
|
||||
// Remove skill from slot
|
||||
const updatedSkills = { ...party.jobSkills }
|
||||
delete updatedSkills[slot as keyof typeof updatedSkills]
|
||||
delete updatedSkills[String(slot) as keyof typeof updatedSkills]
|
||||
|
||||
// Convert skills object to array format expected by API
|
||||
const skillsArray = Object.entries(updatedSkills)
|
||||
|
|
@ -554,6 +554,7 @@
|
|||
if (items.length === 0 || !canEdit()) return
|
||||
|
||||
const item = items[0]
|
||||
if (!item) return
|
||||
loading = true
|
||||
error = null
|
||||
|
||||
|
|
@ -649,7 +650,7 @@
|
|||
localId = partyService.getLocalId()
|
||||
|
||||
// Get edit key for this party if it exists
|
||||
editKey = partyService.getEditKey(party.shortcode)
|
||||
editKey = partyService.getEditKey(party.shortcode) ?? undefined
|
||||
|
||||
// No longer need to verify party data integrity after hydration
|
||||
// since $state.raw prevents the hydration mismatch
|
||||
|
|
@ -787,14 +788,20 @@
|
|||
(c: any) => c.id === gridCharacterId
|
||||
)
|
||||
if (charIndex !== -1) {
|
||||
// Preserve the character object reference but update uncap fields
|
||||
updatedParty.characters[charIndex] = {
|
||||
...updatedParty.characters[charIndex],
|
||||
uncapLevel: updatedChar.uncapLevel ?? updatedChar.uncap_level,
|
||||
transcendenceStep: updatedChar.transcendenceStep ?? updatedChar.transcendence_step
|
||||
// Preserve the character object reference but update uncap fields
|
||||
const existingChar = updatedParty.characters[charIndex]
|
||||
if (existingChar) {
|
||||
updatedParty.characters[charIndex] = {
|
||||
...existingChar,
|
||||
id: existingChar.id,
|
||||
position: existingChar.position,
|
||||
character: existingChar.character,
|
||||
uncapLevel: updatedChar.uncapLevel ?? updatedChar.uncap_level,
|
||||
transcendenceStep: updatedChar.transcendenceStep ?? updatedChar.transcendence_step
|
||||
}
|
||||
}
|
||||
return updatedParty
|
||||
}
|
||||
return updatedParty
|
||||
}
|
||||
}
|
||||
}
|
||||
return party // Return unchanged party if update failed
|
||||
|
|
@ -825,15 +832,21 @@
|
|||
if (updatedParty.weapons) {
|
||||
const weaponIndex = updatedParty.weapons.findIndex((w: any) => w.id === gridWeaponId)
|
||||
if (weaponIndex !== -1) {
|
||||
// Preserve the weapon object reference but update uncap fields
|
||||
updatedParty.weapons[weaponIndex] = {
|
||||
...updatedParty.weapons[weaponIndex],
|
||||
uncapLevel: updatedWeapon.uncapLevel ?? updatedWeapon.uncap_level,
|
||||
transcendenceStep:
|
||||
updatedWeapon.transcendenceStep ?? updatedWeapon.transcendence_step
|
||||
// Preserve the weapon object reference but update uncap fields
|
||||
const existingWeapon = updatedParty.weapons[weaponIndex]
|
||||
if (existingWeapon) {
|
||||
updatedParty.weapons[weaponIndex] = {
|
||||
...existingWeapon,
|
||||
id: existingWeapon.id,
|
||||
position: existingWeapon.position,
|
||||
weapon: existingWeapon.weapon,
|
||||
uncapLevel: updatedWeapon.uncapLevel ?? updatedWeapon.uncap_level,
|
||||
transcendenceStep:
|
||||
updatedWeapon.transcendenceStep ?? updatedWeapon.transcendence_step
|
||||
}
|
||||
}
|
||||
return updatedParty
|
||||
}
|
||||
return updatedParty
|
||||
}
|
||||
}
|
||||
}
|
||||
return party // Return unchanged party if update failed
|
||||
|
|
@ -864,15 +877,21 @@
|
|||
if (updatedParty.summons) {
|
||||
const summonIndex = updatedParty.summons.findIndex((s: any) => s.id === gridSummonId)
|
||||
if (summonIndex !== -1) {
|
||||
// Preserve the summon object reference but update uncap fields
|
||||
updatedParty.summons[summonIndex] = {
|
||||
...updatedParty.summons[summonIndex],
|
||||
uncapLevel: updatedSummon.uncapLevel ?? updatedSummon.uncap_level,
|
||||
transcendenceStep:
|
||||
updatedSummon.transcendenceStep ?? updatedSummon.transcendence_step
|
||||
// Preserve the summon object reference but update uncap fields
|
||||
const existingSummon = updatedParty.summons[summonIndex]
|
||||
if (existingSummon) {
|
||||
updatedParty.summons[summonIndex] = {
|
||||
...existingSummon,
|
||||
id: existingSummon.id,
|
||||
position: existingSummon.position,
|
||||
summon: existingSummon.summon,
|
||||
uncapLevel: updatedSummon.uncapLevel ?? updatedSummon.uncap_level,
|
||||
transcendenceStep:
|
||||
updatedSummon.transcendenceStep ?? updatedSummon.transcendence_step
|
||||
}
|
||||
}
|
||||
return updatedParty
|
||||
}
|
||||
return updatedParty
|
||||
}
|
||||
}
|
||||
}
|
||||
return party // Return unchanged party if update failed
|
||||
|
|
@ -967,26 +986,26 @@
|
|||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content class="dropdown-content" sideOffset={6} align="end">
|
||||
{#if canEdit()}
|
||||
<DropdownItem asChild>
|
||||
<DropdownItem>
|
||||
<button onclick={openEditDialog} disabled={loading}>Edit</button>
|
||||
</DropdownItem>
|
||||
{/if}
|
||||
|
||||
{#if authUserId}
|
||||
<DropdownItem asChild>
|
||||
<DropdownItem>
|
||||
<button onclick={toggleFavorite} disabled={loading}>
|
||||
{party.favorited ? 'Remove from favorites' : 'Add to favorites'}
|
||||
</button>
|
||||
</DropdownItem>
|
||||
{/if}
|
||||
|
||||
<DropdownItem asChild>
|
||||
<DropdownItem>
|
||||
<button onclick={remixParty} disabled={loading}>Remix</button>
|
||||
</DropdownItem>
|
||||
|
||||
{#if party.user?.id === authUserId}
|
||||
<DropdownMenu.Separator class="dropdown-separator" />
|
||||
<DropdownItem asChild>
|
||||
<DropdownItem>
|
||||
<button onclick={() => (deleteDialogOpen = true)} disabled={loading}>
|
||||
Delete
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts">
|
||||
import type { PartyView } from '$lib/api/schemas/party'
|
||||
import type { Party } from '$lib/types/api/party'
|
||||
import GridRep from '$lib/components/reps/GridRep.svelte'
|
||||
|
||||
export let items: PartyView[] = []
|
||||
export let items: Party[] = []
|
||||
</script>
|
||||
|
||||
<ul class="collection" role="list">
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
type: 'character' | 'weapon' | 'summon'
|
||||
item: GridCharacter | GridWeapon | GridSummon
|
||||
itemData: any
|
||||
gridUncapLevel: number | null
|
||||
gridTranscendence: number | null
|
||||
gridUncapLevel: number | null | undefined
|
||||
gridTranscendence: number | null | undefined
|
||||
}
|
||||
|
||||
let { type, item, itemData, gridUncapLevel, gridTranscendence }: Props = $props()
|
||||
|
|
|
|||
|
|
@ -7,21 +7,22 @@
|
|||
type Props = {
|
||||
children: Snippet
|
||||
href?: string
|
||||
asChild?: boolean
|
||||
class?: string
|
||||
}
|
||||
|
||||
const { children, href, asChild = false, class: className = '' }: Props = $props()
|
||||
const { children, href, class: className = '' }: Props = $props()
|
||||
</script>
|
||||
|
||||
{#if href}
|
||||
<DropdownMenu.Item class="dropdown-item {className}" asChild>
|
||||
<a {href}>
|
||||
{@render children()}
|
||||
</a>
|
||||
<DropdownMenu.Item class="dropdown-item {className}">
|
||||
{#snippet child({ props })}
|
||||
<a {...props} {href}>
|
||||
{@render children()}
|
||||
</a>
|
||||
{/snippet}
|
||||
</DropdownMenu.Item>
|
||||
{:else}
|
||||
<DropdownMenu.Item class="dropdown-item {className}" {asChild}>
|
||||
<DropdownMenu.Item class="dropdown-item {className}">
|
||||
{@render children()}
|
||||
</DropdownMenu.Item>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
type?: 'character' | 'weapon' | 'summon'
|
||||
editable?: boolean
|
||||
interactive?: boolean
|
||||
tabIndex?: number
|
||||
tabindex?: number
|
||||
onStarClick?: () => void
|
||||
onFragmentClick?: (newStage: number) => void
|
||||
onFragmentHover?: (newStage: number) => void
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
type = 'character',
|
||||
editable = false,
|
||||
interactive = false,
|
||||
tabIndex,
|
||||
tabindex,
|
||||
onStarClick,
|
||||
onFragmentClick,
|
||||
onFragmentHover
|
||||
|
|
@ -168,7 +168,7 @@
|
|||
onclick={handleClick}
|
||||
onmouseleave={interactive ? handleMouseLeave : undefined}
|
||||
bind:this={starElement}
|
||||
{tabIndex}
|
||||
{tabindex}
|
||||
role={editable ? 'button' : undefined}
|
||||
aria-label={editable ? 'Transcendence star' : undefined}
|
||||
>
|
||||
|
|
@ -399,4 +399,4 @@
|
|||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@
|
|||
|
||||
interface Props {
|
||||
type: 'character' | 'weapon' | 'summon'
|
||||
rarity?: number
|
||||
uncapLevel?: number
|
||||
transcendenceStage?: number
|
||||
flb?: boolean
|
||||
ulb?: boolean
|
||||
transcendence?: boolean
|
||||
special?: boolean
|
||||
className?: string
|
||||
editable?: boolean
|
||||
updateUncap?: (index: number) => void
|
||||
updateTranscendence?: (index: number) => void
|
||||
rarity?: number | undefined
|
||||
uncapLevel?: number | null | undefined
|
||||
transcendenceStage?: number | null | undefined
|
||||
flb?: boolean | undefined
|
||||
ulb?: boolean | undefined
|
||||
transcendence?: boolean | undefined
|
||||
special?: boolean | undefined
|
||||
className?: string | undefined
|
||||
editable?: boolean | undefined
|
||||
updateUncap?: ((index: number) => void) | undefined
|
||||
updateTranscendence?: ((index: number) => void) | undefined
|
||||
}
|
||||
|
||||
interface StarRender {
|
||||
|
|
@ -182,4 +182,4 @@
|
|||
padding: 0;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
flb?: boolean
|
||||
ulb?: boolean
|
||||
index: number
|
||||
tabIndex?: number
|
||||
tabindex?: number
|
||||
onStarClick: (index: number, empty: boolean) => void
|
||||
}
|
||||
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
flb = false,
|
||||
ulb = false,
|
||||
index,
|
||||
tabIndex,
|
||||
tabindex,
|
||||
onStarClick
|
||||
}: Props = $props()
|
||||
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
class:mlb={!special}
|
||||
class:flb
|
||||
class:ulb
|
||||
{tabIndex}
|
||||
{tabindex}
|
||||
onclick={handleClick}
|
||||
role="button"
|
||||
aria-label="Uncap star"
|
||||
|
|
@ -106,4 +106,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ import { sidebar } from '$lib/stores/sidebar.svelte'
|
|||
import DescriptionSidebar from '$lib/components/sidebar/DescriptionSidebar.svelte'
|
||||
|
||||
interface DescriptionSidebarOptions {
|
||||
title?: string
|
||||
description?: string
|
||||
canEdit?: boolean
|
||||
onEdit?: () => void
|
||||
title?: string | undefined
|
||||
description?: string | undefined
|
||||
canEdit?: boolean | undefined
|
||||
onEdit?: (() => void) | undefined
|
||||
}
|
||||
|
||||
export function openDescriptionSidebar(options: DescriptionSidebarOptions) {
|
||||
|
|
@ -22,4 +22,4 @@ export function openDescriptionSidebar(options: DescriptionSidebarOptions) {
|
|||
|
||||
export function closeDescriptionSidebar() {
|
||||
sidebar.close()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,16 @@ import type { Job, JobSkill } from '$lib/types/api/entities'
|
|||
import type { JobSkillList } from '$lib/types/api/party'
|
||||
|
||||
interface JobSelectionOptions {
|
||||
currentJobId?: string
|
||||
onSelectJob?: (job: Job) => void
|
||||
currentJobId?: string | undefined
|
||||
onSelectJob?: ((job: Job) => void) | undefined
|
||||
}
|
||||
|
||||
interface JobSkillSelectionOptions {
|
||||
job?: Job
|
||||
currentSkills?: JobSkillList
|
||||
job?: Job | undefined
|
||||
currentSkills?: JobSkillList | undefined
|
||||
targetSlot: number
|
||||
onSelectSkill?: (skill: JobSkill) => void
|
||||
onRemoveSkill?: () => void
|
||||
onSelectSkill?: ((skill: JobSkill) => void) | undefined
|
||||
onRemoveSkill?: (() => void) | undefined
|
||||
}
|
||||
|
||||
export function openJobSelectionSidebar(options: JobSelectionOptions) {
|
||||
|
|
@ -59,4 +59,4 @@ export function openJobSkillSelectionSidebar(options: JobSkillSelectionOptions)
|
|||
|
||||
export function closeJobSidebar() {
|
||||
sidebar.close()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ export function getImageUrl(
|
|||
id: string | number | null | undefined,
|
||||
variant: ImageVariant,
|
||||
options?: {
|
||||
pose?: string // For character poses
|
||||
element?: number // For element-specific weapon grids
|
||||
pose?: string | undefined // For character poses
|
||||
element?: number | undefined // For element-specific weapon grids
|
||||
}
|
||||
): string {
|
||||
// Return placeholder if no ID
|
||||
|
|
@ -191,4 +191,4 @@ export function getWeaponGridImage(
|
|||
return getImageUrl('weapon', id, 'grid', { element: instanceElement })
|
||||
}
|
||||
return getImageUrl('weapon', id, 'grid')
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue