graphicek/client/src/pages/alerts/components/ContactPointsTable/components/ContactPointFormModal.tsx

157 lines
3.3 KiB
TypeScript

import {
ContactPointInfo,
createContactPoint,
testContactPoint,
updateContactPoint,
} from '@/api/contactPoints'
import { Modal } from '@/components/Modal'
import { useForm } from '@/utils/hooks/useForm'
import { tryParseContactPointConfig } from '@/utils/tryParseContactPointConfig'
import { useMutation, useQueryClient } from 'react-query'
type Props = {
contactPoint?: ContactPointInfo
open: boolean
onClose: () => void
}
type FormValues = {
name: string
type: string
telegramApiKey?: string
telegramTargetChannel?: number
}
export const ContactPointFormModal = ({
open,
onClose,
contactPoint,
}: Props) => {
const queryClient = useQueryClient()
const createMutation = useMutation(createContactPoint)
const updateMutation = useMutation(updateContactPoint)
const testMutation = useMutation(testContactPoint)
const isLoading = createMutation.isLoading || updateMutation.isLoading
const parsedTypeConfig =
contactPoint && tryParseContactPointConfig(contactPoint)
const getTypeConfig = (v: FormValues) => {
if (v.type === 'telegram') {
return {
apiKey: v.telegramApiKey,
targetChannel: v.telegramTargetChannel,
}
}
return {}
}
const { handleSubmit, register, watch, getValues } = useForm({
defaultValue: () => ({
name: contactPoint?.name ?? '',
type: contactPoint?.type ?? 'telegram',
...(parsedTypeConfig?.type === 'telegram' && {
telegramApiKey: parsedTypeConfig.apiKey ?? '',
telegramTargetChannel: parsedTypeConfig.targetChannel,
}),
}),
onSubmit: async (v) => {
if (isLoading) {
return
}
const typeConfig = JSON.stringify(getTypeConfig(v))
if (contactPoint) {
await updateMutation.mutateAsync({
id: contactPoint.id,
name: v.name,
type: v.type,
typeConfig: typeConfig,
})
} else {
await createMutation.mutateAsync({
name: v.name,
type: v.type,
typeConfig: typeConfig,
})
}
queryClient.invalidateQueries('/contact-points')
onClose()
},
})
const type = watch('type')
return (
<Modal open={open} onClose={onClose}>
<form onSubmit={handleSubmit}>
<div className="input">
<label>Name</label>
<input
type="text"
minLength={1}
required
autoFocus
{...register('name')}
/>
</div>
<div className="input">
<label>Type</label>
<select required {...register('type')}>
<option value="telegram">Telegram</option>
</select>
</div>
{type === 'telegram' && (
<>
<div className="input">
<label>API Key</label>
<input
type="text"
minLength={1}
required
{...register('telegramApiKey')}
/>
</div>
<div className="input">
<label>Target Channel</label>
<input
type="text"
minLength={1}
required
{...register('telegramTargetChannel', { type: 'integer' })}
/>
</div>
</>
)}
<div className="actions">
<button
className="test"
type="button"
onClick={() =>
testMutation.mutate({
type: getValues().type,
typeConfig: JSON.stringify(getTypeConfig(getValues())),
})
}
>
Test
</button>
<button className="cancel" type="button" onClick={onClose}>
Cancel
</button>
<button disabled={isLoading}>Save</button>
</div>
</form>
</Modal>
)
}