11import React , { useEffect } from 'react' ;
22import Modal from '@/components/elements/Modal' ;
33import { Task } from '@/api/server/schedules/getServerSchedules' ;
4- import { Form , Formik , Field as FormikField , FormikHelpers } from 'formik' ;
4+ import { Field as FormikField , Form , Formik , FormikHelpers , useFormikContext } from 'formik' ;
55import { ServerContext } from '@/state/server' ;
66import { Actions , useStoreActions } from 'easy-peasy' ;
77import { ApplicationStore } from '@/state' ;
88import createOrUpdateScheduleTask from '@/api/server/schedules/createOrUpdateScheduleTask' ;
99import { httpErrorToHuman } from '@/api/http' ;
1010import Field from '@/components/elements/Field' ;
11- import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper' ;
1211import FlashMessageRender from '@/components/FlashMessageRender' ;
1312import { number , object , string } from 'yup' ;
1413
@@ -26,6 +25,61 @@ interface Values {
2625 timeOffset : string ;
2726}
2827
28+ const TaskDetailsForm = ( { isEditingTask } : { isEditingTask : boolean } ) => {
29+ const { values : { action } , setFieldValue, setFieldTouched } = useFormikContext < Values > ( ) ;
30+
31+ useEffect ( ( ) => {
32+ setFieldValue ( 'payload' , '' ) ;
33+ setFieldTouched ( 'payload' , false ) ;
34+ } , [ action ] ) ;
35+
36+ return (
37+ < Form className = { 'm-0' } >
38+ < h3 className = { 'mb-6' } > Edit Task</ h3 >
39+ < div className = { 'flex' } >
40+ < div className = { 'mr-2' } >
41+ < label className = { 'input-dark-label' } > Action</ label >
42+ < FormikField as = { 'select' } name = { 'action' } className = { 'input-dark' } >
43+ < option value = { 'command' } > Send command</ option >
44+ < option value = { 'power' } > Send power action</ option >
45+ </ FormikField >
46+ </ div >
47+ < div className = { 'flex-1' } >
48+ { action === 'command' ?
49+ < Field
50+ name = { 'payload' }
51+ label = { 'Payload' }
52+ description = { 'The command to send to the server when this task executes.' }
53+ />
54+ :
55+ < div >
56+ < label className = { 'input-dark-label' } > Payload</ label >
57+ < FormikField as = { 'select' } name = { 'payload' } className = { 'input-dark' } >
58+ < option value = { 'start' } > Start the server</ option >
59+ < option value = { 'restart' } > Restart the server</ option >
60+ < option value = { 'stop' } > Stop the server</ option >
61+ < option value = { 'kill' } > Terminate the server</ option >
62+ </ FormikField >
63+ </ div >
64+ }
65+ </ div >
66+ </ div >
67+ < div className = { 'mt-6' } >
68+ < Field
69+ name = { 'timeOffset' }
70+ label = { 'Time offset (in seconds)' }
71+ description = { 'The amount of time to wait after the previous task executes before running this one. If this is the first task on a schedule this will not be applied.' }
72+ />
73+ </ div >
74+ < div className = { 'flex justify-end mt-6' } >
75+ < button type = { 'submit' } className = { 'btn btn-primary btn-sm' } >
76+ { isEditingTask ? 'Save Changes' : 'Create Task' }
77+ </ button >
78+ </ div >
79+ </ Form >
80+ ) ;
81+ } ;
82+
2983export default ( { task, scheduleId, onDismissed } : Props ) => {
3084 const uuid = ServerContext . useStoreState ( state => state . server . data ! . uuid ) ;
3185 const { clearFlashes, addError } = useStoreActions ( ( actions : Actions < ApplicationStore > ) => actions . flashes ) ;
@@ -54,57 +108,23 @@ export default ({ task, scheduleId, onDismissed }: Props) => {
54108 timeOffset : task ?. timeOffset . toString ( ) || '0' ,
55109 } }
56110 validationSchema = { object ( ) . shape ( {
57- action : string ( ) . required ( ) . oneOf ( [ 'command' , 'power' ] ) ,
111+ action : string ( ) . required ( ) . oneOf ( [ 'command' , 'power' ] ) ,
58112 payload : string ( ) . required ( 'A task payload must be provided.' ) ,
59113 timeOffset : number ( ) . typeError ( 'The time offset must be a valid number between 0 and 900.' )
60114 . required ( 'A time offset value must be provided.' )
61115 . min ( 0 , 'The time offset must be at least 0 seconds.' )
62116 . max ( 900 , 'The time offset must be less than 900 seconds.' ) ,
63117 } ) }
64118 >
65- { ( { values , isSubmitting } ) => (
119+ { ( { isSubmitting } ) => (
66120 < Modal
67121 visible = { true }
68122 appear = { true }
69123 onDismissed = { ( ) => onDismissed ( ) }
70124 showSpinnerOverlay = { isSubmitting }
71125 >
72126 < FlashMessageRender byKey = { 'schedule:task' } className = { 'mb-4' } />
73- < Form className = { 'm-0' } >
74- < h3 className = { 'mb-6' } > Edit Task</ h3 >
75- < div className = { 'flex' } >
76- < div className = { 'mr-2' } >
77- < label className = { 'input-dark-label' } > Action</ label >
78- < FormikField as = { 'select' } name = { 'action' } className = { 'input-dark' } >
79- < option value = { 'command' } > Send command</ option >
80- < option value = { 'power' } > Send power action</ option >
81- </ FormikField >
82- </ div >
83- < div className = { 'flex-1' } >
84- < Field
85- name = { 'payload' }
86- label = { 'Payload' }
87- description = {
88- values . action === 'command'
89- ? 'The command to send to the server when this task executes.'
90- : 'The power action to send when this task executes. Options are "start", "stop", "restart", or "kill".'
91- }
92- />
93- </ div >
94- </ div >
95- < div className = { 'mt-6' } >
96- < Field
97- name = { 'timeOffset' }
98- label = { 'Time offset (in seconds)' }
99- description = { 'The amount of time to wait after the previous task executes before running this one. If this is the first task on a schedule this will not be applied.' }
100- />
101- </ div >
102- < div className = { 'flex justify-end mt-6' } >
103- < button type = { 'submit' } className = { 'btn btn-primary btn-sm' } >
104- { task ? 'Save Changes' : 'Create Task' }
105- </ button >
106- </ div >
107- </ Form >
127+ < TaskDetailsForm isEditingTask = { typeof task !== 'undefined' } />
108128 </ Modal >
109129 ) }
110130 </ Formik >
0 commit comments