kleckrelay/src/route-widgets/AliasDetailRoute/ChangeAliasActivationStatusSwitch.tsx
2023-03-05 09:35:02 +01:00

94 lines
2.4 KiB
TypeScript

import {ReactElement, useContext} from "react"
import {AxiosError} from "axios"
import {useTranslation} from "react-i18next"
import update from "immutability-helper"
import {Switch} from "@mui/material"
import {QueryKey, useMutation} from "@tanstack/react-query"
import {Alias, DecryptedAlias} from "~/server-types"
import {UpdateAliasData, updateAlias} from "~/apis"
import {useErrorSuccessSnacks} from "~/hooks"
import {queryClient} from "~/constants/react-query"
import {AuthContext, EncryptionStatus} from "~/components"
import decryptAliasNotes from "~/apis/helpers/decrypt-alias-notes"
export interface ChangeAliasActivationStatusSwitchProps {
id: string
isActive: boolean
queryKey: QueryKey
}
export default function ChangeAliasActivationStatusSwitch({
id,
isActive,
queryKey,
}: ChangeAliasActivationStatusSwitchProps): ReactElement {
const {t} = useTranslation("common")
const {showError, showSuccess} = useErrorSuccessSnacks()
const {_decryptUsingMasterPassword, encryptionStatus} = useContext(AuthContext)
const {mutateAsync, isLoading} = useMutation<
Alias,
AxiosError,
UpdateAliasData,
{previousAlias: DecryptedAlias | Alias | undefined}
>(values => updateAlias(id, values), {
onMutate: async values => {
await queryClient.cancelQueries(queryKey)
const previousAlias = queryClient.getQueryData<DecryptedAlias | Alias>(queryKey)
queryClient.setQueryData<DecryptedAlias | Alias>(queryKey, old =>
update(old, {
isActive: {
$set: values.isActive!,
},
}),
)
return {previousAlias}
},
onSuccess: newAlias => {
if (encryptionStatus === EncryptionStatus.Available) {
;(newAlias as any as DecryptedAlias).notes = decryptAliasNotes(
newAlias.encryptedNotes,
_decryptUsingMasterPassword,
)
}
queryClient.setQueryData<DecryptedAlias | Alias>(queryKey, newAlias)
},
onError: (error, values, context) => {
showError(error)
if (context?.previousAlias) {
queryClient.setQueryData<DecryptedAlias | Alias>(queryKey, context.previousAlias)
}
},
})
return (
<Switch
checked={isActive}
onChange={async () => {
if (isLoading) {
return
}
try {
await mutateAsync({
isActive: !isActive,
})
showSuccess(
isActive
? t("messages.alias.changedToDisabled")
: t("messages.alias.changedToEnabled"),
)
} catch {}
}}
/>
)
}