import { Formik, Form, Field } from 'formik' import { NotificationMethod } from '@prisma/client' import { inferQueryOutput, trpc } from '~/utils/trpc' import { useOrganization } from '~/components/DashboardContext' import IVInputField from '~/components/IVInputField' import IVSelect from '~/components/IVSelect' import { Link } from 'react-router-dom' import IVButton from '~/components/IVButton' type NotificationMethodOption = 'EMAIL' | 'SLACK' | 'ACTION_RUNNER' function validateSlackChannel(value: string | undefined) { if (!value || value === '') { return 'Please select a Slack channel.' } } function validateNotificationEmail(value: string | undefined) { if (!value || value === '') { return 'Please enter an email address.' } } export default function ActionNotificationsSettings({ action, onSuccess, onError, }: { action: inferQueryOutput<'action.one'> onSuccess: () => void onError: () => void refetch: () => void }) { const slackChannels = trpc.useQuery(['organization.slack-channels']) const updateMeta = trpc.useMutation('action.notifications.update') const organization = useOrganization() let defaultNotificationMethod: NotificationMethodOption = 'ACTION_RUNNER' let notificationEmail = '' let slackChannel = '' if ( action.metadata?.defaultNotificationDelivery && typeof action.metadata?.defaultNotificationDelivery === 'string' ) { let delivery = JSON.parse(action.metadata.defaultNotificationDelivery) if (Array.isArray(delivery)) { delivery = delivery[0] if (delivery['method']) { defaultNotificationMethod = delivery['method'] } if (delivery['method'] === 'EMAIL') { notificationEmail = delivery['to'] } if (delivery['method'] === 'SLACK') { slackChannel = delivery['to'] } } } return ( initialValues={{ defaultNotificationMethod, notificationEmail, slackChannel, }} validate={values => { const errors: { [key: string]: string } = {} if (values.defaultNotificationMethod === 'EMAIL') { const emailError = validateNotificationEmail(values.notificationEmail) if (emailError) errors.notificationEmail = emailError } if (values.defaultNotificationMethod === 'SLACK') { if (!organization.connectedToSlack) { errors.defaultNotificationMethod = 'Please connect to Slack first.' } const slackError = validateSlackChannel(values.slackChannel) if (slackError) errors.slackChannel = slackError } return errors }} validateOnBlur={false} validateOnChange={false} onSubmit={async data => { if (updateMeta.isLoading) return let defaultNotificationDelivery: | { method: NotificationMethod; to: string }[] | null = null if (data.defaultNotificationMethod === 'ACTION_RUNNER') { defaultNotificationDelivery = null } else if (data.defaultNotificationMethod === 'EMAIL') { defaultNotificationDelivery = [ { method: 'EMAIL', to: data.notificationEmail, }, ] } else if (data.defaultNotificationMethod === 'SLACK') { defaultNotificationDelivery = [ { method: 'SLACK', to: data.slackChannel, }, ] } updateMeta.mutate( { actionId: action.id, data: { defaultNotificationDelivery, }, }, { onSuccess, onError, } ) }} > {({ values, errors, setFieldValue, setErrors, isValid }) => (
{/* not a "real" setting, per se */}
Notify the action runner
{ setFieldValue('defaultNotificationMethod', e.target.value) setErrors({}) }} />
{values.defaultNotificationMethod === 'EMAIL' && ( { setFieldValue('notificationEmail', e.target.value, true) }} /> )} {values.defaultNotificationMethod === 'SLACK' && ( <> {organization.connectedToSlack ? (
({ label: `#${channel}`, value: `#${channel}`, })) ?? [] } defaultLabel="Select a channel" onChange={e => { setFieldValue( 'slackChannel', e.target.value, true ) }} />
) : (

Please{' '} connect to Slack {' '} first to enable this setting.

)} )}
)} ) }