/**
* Job Mutation Configurations
*
* Provides mutation configurations for job-related operations
* with cache invalidation using TanStack Query v6.
*
* @module api/mutations/job
*/
import { useQueryClient, createMutation } from '@tanstack/svelte-query'
import { partyAdapter } from '$lib/api/adapters/party.adapter'
import { partyKeys } from '$lib/api/queries/party.queries'
import type { Party } from '$lib/types/api/party'
/**
* Update party job mutation
*
* Updates the job for a party with optimistic updates.
*
* @example
* ```svelte
*
* ```
*/
export function useUpdatePartyJob() {
const queryClient = useQueryClient()
return createMutation(() => ({
mutationFn: ({ shortcode, jobId }: { shortcode: string; jobId: string }) =>
partyAdapter.updateJob(shortcode, jobId),
onMutate: async ({ shortcode, jobId }) => {
await queryClient.cancelQueries({ queryKey: partyKeys.detail(shortcode) })
const previousParty = queryClient.getQueryData(partyKeys.detail(shortcode))
// Optimistically update the job ID
// Note: We don't have the full job object here, so we just update the ID
// The full job will be fetched when the query is invalidated
if (previousParty) {
queryClient.setQueryData(partyKeys.detail(shortcode), {
...previousParty,
job: previousParty.job ? { ...previousParty.job, id: jobId } : undefined
})
}
return { previousParty }
},
onError: (_err, { shortcode }, context) => {
if (context?.previousParty) {
queryClient.setQueryData(partyKeys.detail(shortcode), context.previousParty)
}
},
onSettled: (_data, _err, { shortcode }) => {
queryClient.invalidateQueries({ queryKey: partyKeys.detail(shortcode) })
}
}))
}
/**
* Update party job skills mutation
*
* Updates the job skills for a party.
*
* @example
* ```svelte
*
* ```
*/
export function useUpdatePartyJobSkills() {
const queryClient = useQueryClient()
return createMutation(() => ({
mutationFn: ({
shortcode,
skills
}: {
shortcode: string
skills: Array<{ id: string; slot: number }>
}) => partyAdapter.updateJobSkills(shortcode, skills),
onSuccess: (_data, { shortcode }) => {
queryClient.invalidateQueries({ queryKey: partyKeys.detail(shortcode) })
}
}))
}
/**
* Remove party job skill mutation
*
* Removes a job skill from a party.
*
* @example
* ```svelte
*
* ```
*/
export function useRemovePartyJobSkill() {
const queryClient = useQueryClient()
return createMutation(() => ({
mutationFn: ({ shortcode, slot }: { shortcode: string; slot: number }) =>
partyAdapter.removeJobSkill(shortcode, slot),
onMutate: async ({ shortcode, slot }) => {
await queryClient.cancelQueries({ queryKey: partyKeys.detail(shortcode) })
const previousParty = queryClient.getQueryData(partyKeys.detail(shortcode))
// Optimistically remove the skill from the slot
// Convert slot number to string key to match jobSkills type (0-3)
if (previousParty?.jobSkills) {
const updatedSkills = { ...previousParty.jobSkills }
const key = String(slot) as unknown as keyof typeof updatedSkills
delete updatedSkills[key]
queryClient.setQueryData(partyKeys.detail(shortcode), {
...previousParty,
jobSkills: updatedSkills
})
}
return { previousParty }
},
onError: (_err, { shortcode }, context) => {
if (context?.previousParty) {
queryClient.setQueryData(partyKeys.detail(shortcode), context.previousParty)
}
},
onSettled: (_data, _err, { shortcode }) => {
queryClient.invalidateQueries({ queryKey: partyKeys.detail(shortcode) })
}
}))
}
/**
* Update party accessory mutation
*
* Updates the accessory for a party.
*
* @example
* ```svelte
*
* ```
*/
export function useUpdatePartyAccessory() {
const queryClient = useQueryClient()
return createMutation(() => ({
mutationFn: ({ shortcode, accessoryId }: { shortcode: string; accessoryId: string }) =>
partyAdapter.updateAccessory(shortcode, accessoryId),
onSuccess: (_data, { shortcode }) => {
queryClient.invalidateQueries({ queryKey: partyKeys.detail(shortcode) })
}
}))
}