fix: type errors in svelte-main branch (372 -> 217 errors)
- Fix Button variant errors (outlined -> ghost, contained -> primary) - Fix search.queries.ts import path and property names (snake_case -> camelCase) - Fix PartyContext export from party.service.ts - Fix User type missing avatar property - Fix exactOptionalPropertyTypes violations in Unit components - Fix MenuItems Props interface - Fix RequestOptions, SearchParams, SearchFilters types - Fix UpdateUncapParams type - Fix Select.ItemIndicator and maxLength errors - Fix Summon/Weapon hp/atk properties in entity.adapter.ts Co-Authored-By: Justin Edmund <justin@jedmund.com>
This commit is contained in:
parent
0afa6c5308
commit
cab0a84588
16 changed files with 193 additions and 111 deletions
|
|
@ -37,6 +37,29 @@ export interface Weapon {
|
|||
ulbAttack?: number
|
||||
transcendenceHp?: number
|
||||
transcendenceAttack?: number
|
||||
hp?: {
|
||||
minHp?: number
|
||||
maxHp?: number
|
||||
maxHpFlb?: number
|
||||
maxHpUlb?: number
|
||||
}
|
||||
atk?: {
|
||||
minAtk?: number
|
||||
maxAtk?: number
|
||||
maxAtkFlb?: number
|
||||
maxAtkUlb?: number
|
||||
}
|
||||
uncap?: {
|
||||
flb?: boolean
|
||||
ulb?: boolean
|
||||
transcendence?: boolean
|
||||
}
|
||||
maxLevel?: number
|
||||
skillLevelCap?: number
|
||||
weapon_skills?: Array<{
|
||||
name?: string
|
||||
description?: string
|
||||
}>
|
||||
awakenings?: Array<{
|
||||
id: string
|
||||
name: Record<string, string>
|
||||
|
|
@ -109,8 +132,33 @@ export interface Summon {
|
|||
ulbAttack?: number
|
||||
transcendenceHp?: number
|
||||
transcendenceAttack?: number
|
||||
hp?: {
|
||||
minHp?: number
|
||||
maxHp?: number
|
||||
maxHpFlb?: number
|
||||
maxHpUlb?: number
|
||||
maxHpXlb?: number
|
||||
}
|
||||
atk?: {
|
||||
minAtk?: number
|
||||
maxAtk?: number
|
||||
maxAtkFlb?: number
|
||||
maxAtkUlb?: number
|
||||
maxAtkXlb?: number
|
||||
}
|
||||
uncap?: {
|
||||
flb?: boolean
|
||||
ulb?: boolean
|
||||
transcendence?: boolean
|
||||
}
|
||||
subaura?: boolean
|
||||
cooldown?: number
|
||||
callName?: string
|
||||
callDescription?: string
|
||||
auraName?: string
|
||||
auraDescription?: string
|
||||
subAuraName?: string
|
||||
subAuraDescription?: string
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -49,11 +49,11 @@ export interface CreateGridSummonParams {
|
|||
* Parameters for updating uncap levels
|
||||
*/
|
||||
export interface UpdateUncapParams {
|
||||
id?: string
|
||||
id?: string | undefined
|
||||
partyId: string
|
||||
position?: number
|
||||
position?: number | undefined
|
||||
uncapLevel: number
|
||||
transcendenceStep?: number
|
||||
transcendenceStep?: number | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,28 +34,31 @@ export interface AdapterOptions {
|
|||
*/
|
||||
export interface RequestOptions extends Omit<RequestInit, 'body' | 'cache'> {
|
||||
/** Query parameters to append to the URL */
|
||||
params?: Record<string, any>
|
||||
params?: Record<string, any> | undefined
|
||||
|
||||
/** Alternative alias for query parameters */
|
||||
query?: Record<string, any>
|
||||
query?: Record<string, any> | undefined
|
||||
|
||||
/** Request timeout in milliseconds. Overrides the adapter's default timeout */
|
||||
timeout?: number
|
||||
timeout?: number | undefined
|
||||
|
||||
/** Number of retry attempts for this specific request */
|
||||
retries?: number
|
||||
retries?: number | undefined
|
||||
|
||||
/** Cache duration for this request in milliseconds */
|
||||
cacheTime?: number
|
||||
cacheTime?: number | undefined
|
||||
|
||||
/** Request cache mode */
|
||||
cache?: RequestCache
|
||||
cache?: RequestCache | undefined
|
||||
|
||||
/** Alternative alias for cache duration */
|
||||
cacheTTL?: number
|
||||
cacheTTL?: number | undefined
|
||||
|
||||
/** Request body. Can be any serializable value */
|
||||
body?: any
|
||||
|
||||
/** HTTP headers for the request */
|
||||
headers?: Record<string, string> | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -153,28 +156,28 @@ export interface ApiResponse<T> {
|
|||
*/
|
||||
export interface SearchFilters {
|
||||
/** Filter by element IDs */
|
||||
element?: number[]
|
||||
element?: number[] | undefined
|
||||
|
||||
/** Filter by rarity levels */
|
||||
rarity?: number[]
|
||||
rarity?: number[] | undefined
|
||||
|
||||
/** Filter by primary proficiency (weapons and characters) */
|
||||
proficiency1?: number[]
|
||||
proficiency1?: number[] | undefined
|
||||
|
||||
/** Filter by secondary proficiency (characters only) */
|
||||
proficiency2?: number[]
|
||||
proficiency2?: number[] | undefined
|
||||
|
||||
/** Filter by series */
|
||||
series?: number[]
|
||||
series?: number[] | undefined
|
||||
|
||||
/** Include extra/seasonal variants */
|
||||
extra?: boolean
|
||||
extra?: boolean | undefined
|
||||
|
||||
/** Filter summons with sub-aura */
|
||||
subaura?: boolean
|
||||
subaura?: boolean | undefined
|
||||
|
||||
/** Filter special characters */
|
||||
special?: boolean
|
||||
special?: boolean | undefined
|
||||
|
||||
/** Custom filters for specific use cases */
|
||||
[key: string]: any
|
||||
|
|
@ -188,25 +191,25 @@ export interface SearchParams {
|
|||
type: 'weapon' | 'character' | 'summon'
|
||||
|
||||
/** Search query string */
|
||||
query?: string
|
||||
query?: string | undefined
|
||||
|
||||
/** Filters to apply to the search */
|
||||
filters?: SearchFilters
|
||||
filters?: SearchFilters | undefined
|
||||
|
||||
/** Page number for pagination (1-indexed) */
|
||||
page?: number
|
||||
page?: number | undefined
|
||||
|
||||
/** Number of items per page */
|
||||
perPage?: number
|
||||
perPage?: number | undefined
|
||||
|
||||
/** Locale for localized content */
|
||||
locale?: 'en' | 'ja'
|
||||
locale?: 'en' | 'ja' | undefined
|
||||
|
||||
/** Items to exclude from results (by ID) */
|
||||
exclude?: string[]
|
||||
exclude?: string[] | undefined
|
||||
|
||||
/** AbortSignal for request cancellation */
|
||||
signal?: AbortSignal
|
||||
signal?: AbortSignal | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@
|
|||
|
||||
import { infiniteQueryOptions } from '@tanstack/svelte-query'
|
||||
import {
|
||||
searchWeapons,
|
||||
searchCharacters,
|
||||
searchSummons,
|
||||
searchAdapter,
|
||||
type SearchParams
|
||||
} from '$lib/api/resources/search'
|
||||
} from '$lib/api/adapters/search.adapter'
|
||||
|
||||
/**
|
||||
* Filter configuration for search queries
|
||||
|
|
@ -33,14 +31,14 @@ export interface SearchFilters {
|
|||
export interface SearchPageResult {
|
||||
results: Array<{
|
||||
id: string
|
||||
granblue_id: string
|
||||
granblueId: string
|
||||
name: { en?: string; ja?: string }
|
||||
element?: number
|
||||
rarity?: number
|
||||
proficiency?: number
|
||||
series?: number
|
||||
image_url?: string
|
||||
searchable_type: 'Weapon' | 'Character' | 'Summon'
|
||||
imageUrl?: string
|
||||
searchableType: 'Weapon' | 'Character' | 'Summon'
|
||||
}>
|
||||
page: number
|
||||
totalPages: number
|
||||
|
|
@ -131,12 +129,12 @@ export const searchQueries = {
|
|||
queryKey: ['search', 'weapons', query, filters, locale] as const,
|
||||
queryFn: async ({ pageParam }): Promise<SearchPageResult> => {
|
||||
const params = buildSearchParams(query, filters, pageParam, locale)
|
||||
const response = await searchWeapons(params)
|
||||
const response = await searchAdapter.searchWeapons(params)
|
||||
|
||||
return {
|
||||
results: response.results,
|
||||
page: response.meta?.page ?? response.page ?? pageParam,
|
||||
totalPages: response.meta?.total_pages ?? response.total_pages ?? 1
|
||||
totalPages: response.meta?.totalPages ?? response.totalPages ?? 1
|
||||
}
|
||||
},
|
||||
initialPageParam: 1,
|
||||
|
|
@ -163,12 +161,12 @@ export const searchQueries = {
|
|||
queryKey: ['search', 'characters', query, filters, locale] as const,
|
||||
queryFn: async ({ pageParam }): Promise<SearchPageResult> => {
|
||||
const params = buildSearchParams(query, filters, pageParam, locale)
|
||||
const response = await searchCharacters(params)
|
||||
const response = await searchAdapter.searchCharacters(params)
|
||||
|
||||
return {
|
||||
results: response.results,
|
||||
page: response.meta?.page ?? response.page ?? pageParam,
|
||||
totalPages: response.meta?.total_pages ?? response.total_pages ?? 1
|
||||
totalPages: response.meta?.totalPages ?? response.totalPages ?? 1
|
||||
}
|
||||
},
|
||||
initialPageParam: 1,
|
||||
|
|
@ -195,12 +193,12 @@ export const searchQueries = {
|
|||
queryKey: ['search', 'summons', query, filters, locale] as const,
|
||||
queryFn: async ({ pageParam }): Promise<SearchPageResult> => {
|
||||
const params = buildSearchParams(query, filters, pageParam, locale)
|
||||
const response = await searchSummons(params)
|
||||
const response = await searchAdapter.searchSummons(params)
|
||||
|
||||
return {
|
||||
results: response.results,
|
||||
page: response.meta?.page ?? response.page ?? pageParam,
|
||||
totalPages: response.meta?.total_pages ?? response.total_pages ?? 1
|
||||
totalPages: response.meta?.totalPages ?? response.totalPages ?? 1
|
||||
}
|
||||
},
|
||||
initialPageParam: 1,
|
||||
|
|
|
|||
|
|
@ -197,11 +197,11 @@
|
|||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<Button variant="outlined" onclick={handleClose} disabled={saving}>Cancel</Button>
|
||||
<Button type="submit" variant="contained" disabled={saving}>
|
||||
{saving ? 'Saving...' : 'Save Changes'}
|
||||
</Button>
|
||||
</div>
|
||||
<Button variant="ghost" onclick={handleClose} disabled={saving}>Cancel</Button>
|
||||
<Button type="submit" variant="primary" disabled={saving}>
|
||||
{saving ? 'Saving...' : 'Save Changes'}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
{/snippet}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@
|
|||
<div class="error-state">
|
||||
<Icon name="alert-circle" size={32} />
|
||||
<p>{error}</p>
|
||||
<Button size="small" on:click={loadJobs}>Retry</Button>
|
||||
<Button size="small" onclick={loadJobs}>Retry</Button>
|
||||
</div>
|
||||
{:else if Object.keys(filteredJobs).length === 0}
|
||||
<div class="empty-state">
|
||||
|
|
@ -153,8 +153,8 @@
|
|||
{#if searchQuery || selectedTiers.size > 0}
|
||||
<Button
|
||||
size="small"
|
||||
variant="outlined"
|
||||
on:click={() => {
|
||||
variant="ghost"
|
||||
onclick={() => {
|
||||
searchQuery = ''
|
||||
selectedTiers = new Set(['4', '5', 'ex2', 'o1'])
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
{disabled}
|
||||
{readonly}
|
||||
{required}
|
||||
{maxLength}
|
||||
maxlength={maxLength}
|
||||
{...restProps}
|
||||
/>
|
||||
|
||||
|
|
@ -112,16 +112,16 @@
|
|||
</div>
|
||||
{:else}
|
||||
<input
|
||||
bind:value
|
||||
class={inputClasses}
|
||||
{type}
|
||||
{placeholder}
|
||||
{disabled}
|
||||
{readonly}
|
||||
{required}
|
||||
{maxLength}
|
||||
{...restProps}
|
||||
/>
|
||||
bind:value
|
||||
class={inputClasses}
|
||||
{type}
|
||||
{placeholder}
|
||||
{disabled}
|
||||
{readonly}
|
||||
{required}
|
||||
maxlength={maxLength}
|
||||
{...restProps}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if error}
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
{disabled}
|
||||
{readonly}
|
||||
{required}
|
||||
{maxLength}
|
||||
maxlength={maxLength}
|
||||
{...restProps}
|
||||
/>
|
||||
|
||||
|
|
@ -161,16 +161,16 @@
|
|||
</div>
|
||||
{:else}
|
||||
<input
|
||||
bind:value
|
||||
class={inputClasses}
|
||||
{type}
|
||||
{placeholder}
|
||||
{disabled}
|
||||
{readonly}
|
||||
{required}
|
||||
{maxLength}
|
||||
{...restProps}
|
||||
/>
|
||||
bind:value
|
||||
class={inputClasses}
|
||||
{type}
|
||||
{placeholder}
|
||||
{disabled}
|
||||
{readonly}
|
||||
{required}
|
||||
maxlength={maxLength}
|
||||
{...restProps}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
|||
|
|
@ -105,13 +105,17 @@
|
|||
<SelectPrimitive.Viewport>
|
||||
{#each options as option}
|
||||
<SelectPrimitive.Item value={String(option.value)} disabled={option.disabled} class="item">
|
||||
{#if option.image}
|
||||
<img src={option.image} alt={option.label} class="image" />
|
||||
{/if}
|
||||
<span class="text">{option.label}</span>
|
||||
<SelectPrimitive.ItemIndicator class="indicator">
|
||||
<Icon name="check" size={14} />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
{#snippet children({ selected })}
|
||||
{#if option.image}
|
||||
<img src={option.image} alt={option.label} class="image" />
|
||||
{/if}
|
||||
<span class="text">{option.label}</span>
|
||||
{#if selected}
|
||||
<span class="indicator">
|
||||
<Icon name="check" size={14} />
|
||||
</span>
|
||||
{/if}
|
||||
{/snippet}
|
||||
</SelectPrimitive.Item>
|
||||
{/each}
|
||||
</SelectPrimitive.Viewport>
|
||||
|
|
@ -135,14 +139,18 @@
|
|||
<SelectPrimitive.Content class="content">
|
||||
<SelectPrimitive.Viewport>
|
||||
{#each options as option}
|
||||
<SelectPrimitive.Item value={String(option.value)} disabled={option.disabled} class="item">
|
||||
{#if option.image}
|
||||
<img src={option.image} alt={option.label} class="image" />
|
||||
{/if}
|
||||
<span class="text">{option.label}</span>
|
||||
<SelectPrimitive.ItemIndicator class="indicator">
|
||||
<Icon name="check" size={14} />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
<SelectPrimitive.Item value={String(option.value)} disabled={option.disabled} class="item">
|
||||
{#snippet children({ selected })}
|
||||
{#if option.image}
|
||||
<img src={option.image} alt={option.label} class="image" />
|
||||
{/if}
|
||||
<span class="text">{option.label}</span>
|
||||
{#if selected}
|
||||
<span class="indicator">
|
||||
<Icon name="check" size={14} />
|
||||
</span>
|
||||
{/if}
|
||||
{/snippet}
|
||||
</SelectPrimitive.Item>
|
||||
{/each}
|
||||
</SelectPrimitive.Viewport>
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
import { ContextMenu, DropdownMenu } from 'bits-ui'
|
||||
|
||||
interface MenuItemsProps {
|
||||
onViewDetails?: () => void
|
||||
onReplace?: () => void
|
||||
onRemove?: () => void
|
||||
canEdit?: boolean
|
||||
onViewDetails?: (() => void) | undefined
|
||||
onReplace?: (() => void) | undefined
|
||||
onRemove?: (() => void | Promise<void>) | undefined
|
||||
canEdit?: boolean | undefined
|
||||
variant?: 'context' | 'dropdown'
|
||||
viewDetailsLabel?: string
|
||||
replaceLabel?: string
|
||||
removeLabel?: string
|
||||
viewDetailsLabel?: string | undefined
|
||||
replaceLabel?: string | undefined
|
||||
removeLabel?: string | undefined
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@
|
|||
import * as m from '$lib/paraglide/messages'
|
||||
|
||||
interface Props {
|
||||
item?: GridCharacter
|
||||
item?: GridCharacter | undefined
|
||||
position: number
|
||||
mainWeaponElement?: number | null
|
||||
partyElement?: number | null
|
||||
job?: Job
|
||||
mainWeaponElement?: number | null | undefined
|
||||
partyElement?: number | null | undefined
|
||||
job?: Job | undefined
|
||||
}
|
||||
|
||||
let { item, position, mainWeaponElement, partyElement, job }: Props = $props()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
import * as m from '$lib/paraglide/messages'
|
||||
|
||||
interface Props {
|
||||
item?: GridSummon
|
||||
item?: GridSummon | undefined
|
||||
position: number
|
||||
}
|
||||
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
canEdit: () => boolean
|
||||
getEditKey: () => string | null
|
||||
services: { gridService: any; partyService: any }
|
||||
openPicker?: (opts: { type: 'weapon' | 'summon' | 'character'; position: number; item?: any }) => void
|
||||
}
|
||||
const ctx = getContext<PartyCtx>('party')
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
import * as m from '$lib/paraglide/messages'
|
||||
|
||||
interface Props {
|
||||
item?: GridWeapon
|
||||
item?: GridWeapon | undefined
|
||||
position: number
|
||||
}
|
||||
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
canEdit: () => boolean
|
||||
getEditKey: () => string | null
|
||||
services: { gridService: any; partyService: any }
|
||||
openPicker?: (opts: { type: 'weapon' | 'summon' | 'character'; position: number; item?: any }) => void
|
||||
}
|
||||
|
||||
const ctx = getContext<PartyCtx>('party')
|
||||
|
|
|
|||
|
|
@ -3,6 +3,18 @@ import { partyAdapter } from '$lib/api/adapters/party.adapter'
|
|||
import { authStore } from '$lib/stores/auth.store'
|
||||
import { browser } from '$app/environment'
|
||||
|
||||
/**
|
||||
* Context type for party-related operations in components
|
||||
*/
|
||||
export interface PartyContext {
|
||||
getParty: () => Party
|
||||
updateParty: (p: Party) => void
|
||||
canEdit: () => boolean
|
||||
getEditKey: () => string | null
|
||||
services: { gridService: any; partyService: any }
|
||||
openPicker?: (opts: { type: 'weapon' | 'summon' | 'character'; position: number; item?: any }) => void
|
||||
}
|
||||
|
||||
export interface EditabilityResult {
|
||||
canEdit: boolean
|
||||
headers?: Record<string, string>
|
||||
|
|
|
|||
|
|
@ -194,4 +194,8 @@ export interface User {
|
|||
role?: string
|
||||
createdAt?: string
|
||||
updatedAt?: string
|
||||
avatar?: {
|
||||
picture?: string
|
||||
element?: string
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,20 +204,20 @@
|
|||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<Button
|
||||
variant="outlined"
|
||||
href="/me"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
disabled={saving}
|
||||
>
|
||||
{saving ? 'Saving...' : 'Save Changes'}
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
href="/me"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
disabled={saving}
|
||||
>
|
||||
{saving ? 'Saving...' : 'Save Changes'}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -363,4 +363,4 @@
|
|||
padding-top: spacing.$unit-2x;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -98,6 +98,12 @@
|
|||
if (!partyId && !isCreatingParty && items.length > 0) {
|
||||
isCreatingParty = true
|
||||
const firstItem = items[0]
|
||||
|
||||
// Guard against undefined firstItem (shouldn't happen given items.length > 0 check, but TypeScript needs this)
|
||||
if (!firstItem) {
|
||||
isCreatingParty = false
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// Step 1: Create the party (with local_id only for anonymous users)
|
||||
|
|
@ -262,6 +268,7 @@
|
|||
try {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i]
|
||||
if (!item) continue // Skip undefined items
|
||||
let position = -1 // Default position
|
||||
|
||||
if (activeTab === GridType.Weapon) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue