Skip to content

Instantly share code, notes, and snippets.

@MichaelrMentele
Created February 22, 2023 21:41
Show Gist options
  • Save MichaelrMentele/ffabe9a9af014ddbde7d8885a03ceab0 to your computer and use it in GitHub Desktop.
Save MichaelrMentele/ffabe9a9af014ddbde7d8885a03ceab0 to your computer and use it in GitHub Desktop.
import { useMutation } from '@apollo/client'
import lodash from 'lodash'
import {
CreateLienholderInput,
CreateLienholderMutation,
CreateLienholderMutationVariables,
DeleteLienholderMutation,
DeleteLienholderMutationVariables,
FindLienholdersQuery,
Lienholder,
UpdateLienholderInput,
UpdateLienholderMutation,
UpdateLienholderMutationVariables,
} from 'types/graphql'
import {
ADDRESS_FIELDS,
CUSTOMER_DEAL_FIELDS,
DEAL_TRADE_IN_FIELDS,
GET_LIENHOLDERS,
LIENHOLDER_FIELDS,
} from 'src/gql'
export const CREATE_LIENHOLDER = gql`
${LIENHOLDER_FIELDS}
${ADDRESS_FIELDS}
${CUSTOMER_DEAL_FIELDS}
${DEAL_TRADE_IN_FIELDS}
mutation CreateLienholderMutation($input: CreateLienholderInput!) {
createLienholder(input: $input) {
...LienholderFields
address {
...CoreAddressFields
}
customerDeals {
...CustomerDealFields
}
tradeIns {
...DealTradeInFields
}
}
}
`
export const UPDATE_LIENHOLDER = gql`
${LIENHOLDER_FIELDS}
${ADDRESS_FIELDS}
mutation UpdateLienholderMutation($id: Int!, $input: UpdateLienholderInput!) {
updateLienholder(id: $id, input: $input) {
...LienholderFields
address {
...CoreAddressFields
}
}
}
`
export const DELETE_LIENHOLDER = gql`
mutation DeleteLienholderMutation($id: Int!) {
deleteLienholder(id: $id) {
id
}
}
`
interface LienholderAlreadyExists {
id?: number
externalId: string
name: string
}
interface UseLienholdersHook {
lienholders: [Lienholder]
}
/**
* Hook to create update and delete Lienholders with validations and cache updates for gql
*
* @param {string} lienholders - lienholders from the query or cache
*/
export function useLienholders(args: UseLienholdersHook) {
const { lienholders } = args
// ********* MUTATIONS *********
const [createLienholderMutation] = useMutation<
CreateLienholderMutation,
CreateLienholderMutationVariables
>(CREATE_LIENHOLDER, {
update: (cache, mutationResult) => {
const lienholdersFromCache = cache.readQuery<FindLienholdersQuery>({
query: GET_LIENHOLDERS,
})
const newLienholder = mutationResult.data.createLienholder
const newLienholders = lodash.cloneDeep(lienholdersFromCache.lienholders)
newLienholders.push(newLienholder)
cache.writeQuery({
query: GET_LIENHOLDERS,
data: { lienholders: newLienholders },
})
},
})
const [updateLienholderMutation] = useMutation<
UpdateLienholderMutation,
UpdateLienholderMutationVariables
>(UPDATE_LIENHOLDER, {
update: (cache, mutationResult) => {
const { address, ...newLienholder } = mutationResult.data.updateLienholder
cache.writeFragment({
id: `Lienholder:${mutationResult.data.updateLienholder.id}`,
fragment: LIENHOLDER_FIELDS,
data: newLienholder,
})
cache.writeFragment({
id: `Address:${mutationResult.data.updateLienholder?.address?.id}`,
fragment: ADDRESS_FIELDS,
data: address,
})
return mutationResult
},
})
const [deleteLienholderMutation] = useMutation<
DeleteLienholderMutation,
DeleteLienholderMutationVariables
>(DELETE_LIENHOLDER, {
update: (cache, mutationResult) => {
// UPSTACK: Will add proper cache update here
console.log('deleted lienholder: ', mutationResult.data)
return mutationResult
},
})
// ********* VALIDATIONS *********
const lienholderAlreadyExists = (args: LienholderAlreadyExists) => {
const { id, externalId, name } = args
const alreadyExists = lienholders
? lienholders.find((lienholder) => {
if (
lienholder.externalId === externalId ||
lienholder.name === name ||
lienholder.id === id
) {
return true
}
})
: false
return alreadyExists
}
/**
* If the address object has any properties, clean the address object, otherwise delete the address
* object
* @param newLienholderData - The data that the user entered into the form.
*/
const cleanCreateLienholderInput = (newLienholderData) => {
let addressIsValid = false
Object.keys(newLienholderData.address).every((field) => {
if (newLienholderData.address[field]) {
addressIsValid = true
return false
}
return true
})
let result = cleanExternalIdInput(newLienholderData)
if (addressIsValid) {
result = cleanAddressInput(result)
} else {
delete result.address
}
return result
}
/**
* - Sets address.state to null if it's empty
* - if the type is empty, pass 'primary' instead.
* @param newLienholderData - The data that will be sent to the API.
*/
const cleanAddressInput = (newLienholderData) => {
const result = lodash.cloneDeep(newLienholderData)
for (const key in result.address) {
if (result.address[key] === '') {
// Don't pass empty strings to backend
result.address[key] = null
}
}
delete result.address.id
result['address'] = {
...result.address,
// Don't pass empty string for type
type: result.address.type || 'primary',
}
return result
}
const cleanExternalIdInput = (newLienholderData) => {
const result = lodash.cloneDeep(newLienholderData)
if (!result.externalId) {
// Don't pass empty string for state
result.externalId = null
}
return result
}
// ********* COMMANDS *********
const updateLienholder = async (id: number, input: UpdateLienholderInput) => {
const { externalId, name } = input
const alreadyExists = lienholderAlreadyExists({ id, externalId, name })
if (!alreadyExists) {
throw new Error('Lienholder does not exist')
}
const cleanedInput = cleanExternalIdInput(cleanAddressInput(input))
return await updateLienholderMutation({
variables: {
id,
input: cleanedInput,
},
})
}
const createLienholder = async (input: CreateLienholderInput) => {
const { externalId, name } = input
const alreadyExists = lienholderAlreadyExists({ externalId, name })
if (alreadyExists) {
throw new Error('Lienholder already exists')
}
const cleanedInput = cleanCreateLienholderInput(input)
return await createLienholderMutation({
variables: {
input: cleanedInput,
},
})
}
// ********* COMMANDS *********`
const deleteLienholder = (id: number) => {
deleteLienholderMutation({
variables: {
id,
},
})
}
return {
createLienholder,
deleteLienholder,
updateLienholder,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment