11import { zodResolver } from "@hookform/resolvers/zod" ;
2- import {
3- AlertTriangle ,
4- Mail ,
5- MessageCircleMore ,
6- PenBoxIcon ,
7- PlusIcon ,
8- } from "lucide-react" ;
2+ import { AlertTriangle , Mail , PenBoxIcon , PlusIcon } from "lucide-react" ;
93import { useEffect , useState } from "react" ;
104import { useFieldArray , useForm } from "react-hook-form" ;
115import { toast } from "sonner" ;
126import { z } from "zod" ;
137import {
148 DiscordIcon ,
159 GotifyIcon ,
10+ LarkIcon ,
1611 NtfyIcon ,
1712 SlackIcon ,
1813 TelegramIcon ,
@@ -112,6 +107,12 @@ export const notificationSchema = z.discriminatedUnion("type", [
112107 priority : z . number ( ) . min ( 1 ) . max ( 5 ) . default ( 3 ) ,
113108 } )
114109 . merge ( notificationBaseSchema ) ,
110+ z
111+ . object ( {
112+ type : z . literal ( "lark" ) ,
113+ webhookUrl : z . string ( ) . min ( 1 , { message : "Webhook URL is required" } ) ,
114+ } )
115+ . merge ( notificationBaseSchema ) ,
115116] ) ;
116117
117118export const notificationsMap = {
@@ -127,6 +128,10 @@ export const notificationsMap = {
127128 icon : < DiscordIcon /> ,
128129 label : "Discord" ,
129130 } ,
131+ lark : {
132+ icon : < LarkIcon className = "text-muted-foreground" /> ,
133+ label : "Lark" ,
134+ } ,
130135 email : {
131136 icon : < Mail size = { 29 } className = "text-muted-foreground" /> ,
132137 label : "Email" ,
@@ -172,6 +177,8 @@ export const HandleNotifications = ({ notificationId }: Props) => {
172177 api . notification . testGotifyConnection . useMutation ( ) ;
173178 const { mutateAsync : testNtfyConnection , isLoading : isLoadingNtfy } =
174179 api . notification . testNtfyConnection . useMutation ( ) ;
180+ const { mutateAsync : testLarkConnection , isLoading : isLoadingLark } =
181+ api . notification . testLarkConnection . useMutation ( ) ;
175182 const slackMutation = notificationId
176183 ? api . notification . updateSlack . useMutation ( )
177184 : api . notification . createSlack . useMutation ( ) ;
@@ -190,6 +197,9 @@ export const HandleNotifications = ({ notificationId }: Props) => {
190197 const ntfyMutation = notificationId
191198 ? api . notification . updateNtfy . useMutation ( )
192199 : api . notification . createNtfy . useMutation ( ) ;
200+ const larkMutation = notificationId
201+ ? api . notification . updateLark . useMutation ( )
202+ : api . notification . createLark . useMutation ( ) ;
193203
194204 const form = useForm < NotificationSchema > ( {
195205 defaultValues : {
@@ -299,6 +309,19 @@ export const HandleNotifications = ({ notificationId }: Props) => {
299309 serverUrl : notification . ntfy ?. serverUrl ,
300310 name : notification . name ,
301311 dockerCleanup : notification . dockerCleanup ,
312+ serverThreshold : notification . serverThreshold ,
313+ } ) ;
314+ } else if ( notification . notificationType === "lark" ) {
315+ form . reset ( {
316+ appBuildError : notification . appBuildError ,
317+ appDeploy : notification . appDeploy ,
318+ dokployRestart : notification . dokployRestart ,
319+ databaseBackup : notification . databaseBackup ,
320+ type : notification . notificationType ,
321+ webhookUrl : notification . lark ?. webhookUrl ,
322+ name : notification . name ,
323+ dockerCleanup : notification . dockerCleanup ,
324+ serverThreshold : notification . serverThreshold ,
302325 } ) ;
303326 }
304327 } else {
@@ -313,6 +336,7 @@ export const HandleNotifications = ({ notificationId }: Props) => {
313336 email : emailMutation ,
314337 gotify : gotifyMutation ,
315338 ntfy : ntfyMutation ,
339+ lark : larkMutation ,
316340 } ;
317341
318342 const onSubmit = async ( data : NotificationSchema ) => {
@@ -416,6 +440,19 @@ export const HandleNotifications = ({ notificationId }: Props) => {
416440 notificationId : notificationId || "" ,
417441 ntfyId : notification ?. ntfyId || "" ,
418442 } ) ;
443+ } else if ( data . type === "lark" ) {
444+ promise = larkMutation . mutateAsync ( {
445+ appBuildError : appBuildError ,
446+ appDeploy : appDeploy ,
447+ dokployRestart : dokployRestart ,
448+ databaseBackup : databaseBackup ,
449+ webhookUrl : data . webhookUrl ,
450+ name : data . name ,
451+ dockerCleanup : dockerCleanup ,
452+ notificationId : notificationId || "" ,
453+ larkId : notification ?. larkId || "" ,
454+ serverThreshold : serverThreshold ,
455+ } ) ;
419456 }
420457
421458 if ( promise ) {
@@ -504,7 +541,7 @@ export const HandleNotifications = ({ notificationId }: Props) => {
504541 />
505542 < Label
506543 htmlFor = { key }
507- className = "flex flex-col gap-2 items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary cursor-pointer"
544+ className = "h-24 flex flex-col gap-2 items-center justify-between rounded-md border-2 border-muted bg-popover p-4 hover:bg-accent hover:text-accent-foreground peer-data-[state=checked]:border-primary [&:has([data-state=checked])]:border-primary cursor-pointer"
508545 >
509546 { value . icon }
510547 { value . label }
@@ -1002,6 +1039,27 @@ export const HandleNotifications = ({ notificationId }: Props) => {
10021039 />
10031040 </ >
10041041 ) }
1042+
1043+ { type === "lark" && (
1044+ < >
1045+ < FormField
1046+ control = { form . control }
1047+ name = "webhookUrl"
1048+ render = { ( { field } ) => (
1049+ < FormItem >
1050+ < FormLabel > Webhook URL</ FormLabel >
1051+ < FormControl >
1052+ < Input
1053+ placeholder = "https://open.larksuite.com/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxxxxxxxxx"
1054+ { ...field }
1055+ />
1056+ </ FormControl >
1057+ < FormMessage />
1058+ </ FormItem >
1059+ ) }
1060+ />
1061+ </ >
1062+ ) }
10051063 </ div >
10061064 </ div >
10071065 < div className = "flex flex-col gap-4" >
@@ -1152,7 +1210,8 @@ export const HandleNotifications = ({ notificationId }: Props) => {
11521210 isLoadingDiscord ||
11531211 isLoadingEmail ||
11541212 isLoadingGotify ||
1155- isLoadingNtfy
1213+ isLoadingNtfy ||
1214+ isLoadingLark
11561215 }
11571216 variant = "secondary"
11581217 onClick = { async ( ) => {
@@ -1196,6 +1255,10 @@ export const HandleNotifications = ({ notificationId }: Props) => {
11961255 accessToken : form . getValues ( "accessToken" ) ,
11971256 priority : form . getValues ( "priority" ) ,
11981257 } ) ;
1258+ } else if ( type === "lark" ) {
1259+ await testLarkConnection ( {
1260+ webhookUrl : form . getValues ( "webhookUrl" ) ,
1261+ } ) ;
11991262 }
12001263 toast . success ( "Connection Success" ) ;
12011264 } catch {
0 commit comments