diff --git a/apps/fe/.env.example b/apps/fe/.env.example index b001ed2..ccdc226 100644 --- a/apps/fe/.env.example +++ b/apps/fe/.env.example @@ -6,4 +6,6 @@ AUTH_GOOGLE_ID= AUTH_GOOGLE_SECRET= AUTH_GITHUB_ID= -AUTH_GITHUB_SECRET= \ No newline at end of file +AUTH_GITHUB_SECRET= + +NEXT_DISCORD_APP_AUTHORIZE_URL="https://discord.com/oauth2/authorize?client_id=1276071272467660881" diff --git a/apps/fe/src/components/form-item/index.ts b/apps/fe/src/components/form-item/index.ts new file mode 100644 index 0000000..60c40c0 --- /dev/null +++ b/apps/fe/src/components/form-item/index.ts @@ -0,0 +1 @@ +export * from './task-form-item'; diff --git a/apps/fe/src/components/form-item/task-form-item/alert-option.tsx b/apps/fe/src/components/form-item/task-form-item/alert-option.tsx new file mode 100644 index 0000000..1ab676f --- /dev/null +++ b/apps/fe/src/components/form-item/task-form-item/alert-option.tsx @@ -0,0 +1,168 @@ +import { Divider, Space, Form, Checkbox, Input, Typography, Alert } from 'antd'; +import { Control, Controller, FieldErrors, UseFormSetValue } from 'react-hook-form'; +import { useState, useEffect } from 'react'; + +import { TaskFormValues } from '~/components/form/task-form'; + +const { Item } = Form; + +export function AlertOptions({ + control, + errors, + setValue, +}: { + control: Control>; + errors: FieldErrors; + setValue: UseFormSetValue; +}) { + const [showDiscordOptions, setShowDiscordOptions] = useState(false); + + useEffect(() => { + const dmUserId = control._formValues.options?.alert?.alertOn?.discord?.dmUserId; + const channelId = control._formValues.options?.alert?.alertOn?.discord?.channelId; + if (dmUserId || channelId) { + setShowDiscordOptions(true); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if (!showDiscordOptions) { + setValue('options.alert.alertOn.discord.dmUserId', ''); + setValue('options.alert.alertOn.discord.channelId', ''); + } + }, [showDiscordOptions, setValue]); + + return ( + <> + Notify me when + + + name={'options.alert.jobExecutionFailed'} + control={control} + render={({ field }) => ( + + + Job execution failed + + + )} + /> + + name={'options.alert.disableByTooManyFailures'} + control={control} + render={({ field }) => ( + + + Job is disabled by too many failures + + + )} + /> + + Notify me on: + + + name={'options.alert.alertOn.email'} + control={control} + render={({ field }) => ( + + + Email + + + )} + /> + setShowDiscordOptions(e.target.checked)} + > + Discord + + {showDiscordOptions && ( + <> + + To receive Discord notifications, please make sure our bot is + allowed to send messages to you.{' '} + + Click here + {' '} + to authorize. + + } + type="info" + showIcon + /> + + + name={'options.alert.alertOn.discord.dmUserId'} + control={control} + render={({ field: { ref, ...field } }) => ( + + { + errors?.options?.alert?.alertOn?.discord + ?.dmUserId?.message + } + + } + noStyle + > + + + )} + /> + + name={'options.alert.alertOn.discord.channelId'} + control={control} + render={({ field: { ref, ...field } }) => ( + + { + errors?.options?.alert?.alertOn?.discord + ?.channelId?.message + } + + } + noStyle + > + + + )} + /> + + + )} + + + ); +} diff --git a/apps/fe/src/components/form-item/task-form-item/index.ts b/apps/fe/src/components/form-item/task-form-item/index.ts new file mode 100644 index 0000000..065cb9a --- /dev/null +++ b/apps/fe/src/components/form-item/task-form-item/index.ts @@ -0,0 +1 @@ +export * from './alert-option'; diff --git a/apps/fe/src/components/form/task-form.tsx b/apps/fe/src/components/form/task-form.tsx index 66aae74..764a431 100644 --- a/apps/fe/src/components/form/task-form.tsx +++ b/apps/fe/src/components/form/task-form.tsx @@ -5,7 +5,6 @@ import 'react-js-cron/dist/styles.css'; import { useEffect } from 'react'; import { Controller, useFieldArray } from 'react-hook-form'; import { - Checkbox, Form, Input, Select, @@ -32,6 +31,7 @@ import worldTimeAPIProvider from '~/providers/data-provider/timezone'; import { useCronReducer } from '~/hooks/useCronReducer'; import { HttpMethodTag } from '~/components/tag/http-method-tag'; import { TryRequestButton } from '../button/try-request-btn'; +import { AlertOptions } from '../form-item'; const { Item } = Form; const { Text } = Typography; @@ -474,101 +474,8 @@ export function TaskForm({ mode, defaultValues, onSubmit, formProps }: TaskFormP )} /> - Notify me when - - - name={'options.alert.jobExecutionFailed'} - control={control} - render={({ field }) => ( - - - Job execution failed - - - )} - /> - - name={'options.alert.disableByTooManyFailures'} - control={control} - render={({ field }) => ( - - - Job is disabled by too many failures - - - )} - /> - - Notify me on: - - - name={'options.alert.alertOn.email'} - control={control} - render={({ field }) => ( - - - Email - - - )} - /> - - - name={'options.alert.alertOn.discord.dmUserId'} - control={control} - render={({ field: { ref, ...field } }) => ( - - { - errors?.options?.alert?.alertOn?.discord?.dmUserId - ?.message - } - - } - > - - - )} - /> - - name={'options.alert.alertOn.discord.channelId'} - control={control} - render={({ field: { ref, ...field } }) => ( - - { - errors?.options?.alert?.alertOn?.discord?.channelId - ?.message - } - - } - > - - - )} - /> - - + + );