11import { zodResolver } from "@hookform/resolvers/zod" ;
2+ import { Plus , Trash2 } from "lucide-react" ;
23import { useEffect } from "react" ;
3- import { useForm } from "react-hook-form" ;
4+ import { useFieldArray , useForm } from "react-hook-form" ;
45import { toast } from "sonner" ;
56import { z } from "zod" ;
67import { Button } from "@/components/ui/button" ;
@@ -20,6 +21,13 @@ import type { ServiceType } from "../../application/advanced/show-resources";
2021const addDockerImage = z . object ( {
2122 dockerImage : z . string ( ) . min ( 1 , "Docker image is required" ) ,
2223 command : z . string ( ) ,
24+ args : z
25+ . array (
26+ z . object ( {
27+ value : z . string ( ) . min ( 1 , "Argument cannot be empty" ) ,
28+ } ) ,
29+ )
30+ . optional ( ) ,
2331} ) ;
2432
2533interface Props {
@@ -61,15 +69,22 @@ export const ShowCustomCommand = ({ id, type }: Props) => {
6169 defaultValues : {
6270 dockerImage : "" ,
6371 command : "" ,
72+ args : [ ] ,
6473 } ,
6574 resolver : zodResolver ( addDockerImage ) ,
6675 } ) ;
6776
77+ const { fields, append, remove } = useFieldArray ( {
78+ control : form . control ,
79+ name : "args" ,
80+ } ) ;
81+
6882 useEffect ( ( ) => {
6983 if ( data ) {
7084 form . reset ( {
7185 dockerImage : data . dockerImage ,
7286 command : data . command || "" ,
87+ args : data . args ?. map ( ( arg ) => ( { value : arg } ) ) || [ ] ,
7388 } ) ;
7489 }
7590 } , [ data , form , form . reset ] ) ;
@@ -83,6 +98,7 @@ export const ShowCustomCommand = ({ id, type }: Props) => {
8398 mariadbId : id || "" ,
8499 dockerImage : formData ?. dockerImage ,
85100 command : formData ?. command ,
101+ args : formData ?. args ?. map ( ( arg ) => arg . value ) . filter ( Boolean ) ,
86102 } )
87103 . then ( async ( ) => {
88104 toast . success ( "Custom Command Updated" ) ;
@@ -128,13 +144,68 @@ export const ShowCustomCommand = ({ id, type }: Props) => {
128144 < FormItem >
129145 < FormLabel > Command</ FormLabel >
130146 < FormControl >
131- < Input placeholder = "Custom command " { ...field } />
147+ < Input placeholder = "/bin/sh " { ...field } />
132148 </ FormControl >
133149
134150 < FormMessage />
135151 </ FormItem >
136152 ) }
137153 />
154+
155+ < div className = "space-y-2" >
156+ < div className = "flex items-center justify-between" >
157+ < FormLabel > Arguments (Args)</ FormLabel >
158+ < Button
159+ type = "button"
160+ variant = "outline"
161+ size = "sm"
162+ onClick = { ( ) => append ( { value : "" } ) }
163+ >
164+ < Plus className = "h-4 w-4 mr-1" />
165+ Add Argument
166+ </ Button >
167+ </ div >
168+
169+ { fields . length === 0 && (
170+ < p className = "text-sm text-muted-foreground" >
171+ No arguments added yet. Click "Add Argument" to add one.
172+ </ p >
173+ ) }
174+
175+ { fields . map ( ( field , index ) => (
176+ < FormField
177+ key = { field . id }
178+ control = { form . control }
179+ name = { `args.${ index } .value` }
180+ render = { ( { field } ) => (
181+ < FormItem >
182+ < div className = "flex gap-2" >
183+ < FormControl >
184+ < Input
185+ placeholder = {
186+ index === 0
187+ ? "-c"
188+ : "redis-server --port 6379"
189+ }
190+ { ...field }
191+ />
192+ </ FormControl >
193+ < Button
194+ type = "button"
195+ variant = "destructive"
196+ size = "icon"
197+ onClick = { ( ) => remove ( index ) }
198+ >
199+ < Trash2 className = "h-4 w-4" />
200+ </ Button >
201+ </ div >
202+ < FormMessage />
203+ </ FormItem >
204+ ) }
205+ />
206+ ) ) }
207+ </ div >
208+
138209 < div className = "flex w-full justify-end" >
139210 < Button isLoading = { form . formState . isSubmitting } type = "submit" >
140211 Save
0 commit comments