2021-09-16 03:19:39 +00:00
import getEgg , { Egg , EggVariable } from '@/api/admin/eggs/getEgg' ;
import { Server } from '@/api/admin/servers/getServers' ;
2021-09-16 20:59:22 +00:00
import updateServerStartup , { Values } from '@/api/admin/servers/updateServerStartup' ;
2021-09-13 05:50:12 +00:00
import EggSelect from '@/components/admin/servers/EggSelect' ;
import NestSelect from '@/components/admin/servers/NestSelect' ;
2021-09-16 20:59:22 +00:00
import { Context , ServerIncludes } from '@/components/admin/servers/ServerRouter' ;
2021-05-20 22:00:46 +00:00
import FormikSwitch from '@/components/elements/FormikSwitch' ;
2021-09-16 03:19:39 +00:00
import React , { useEffect , useState } from 'react' ;
2021-09-13 05:50:12 +00:00
import Button from '@/components/elements/Button' ;
2021-05-20 22:00:46 +00:00
import Input from '@/components/elements/Input' ;
import AdminBox from '@/components/admin/AdminBox' ;
import tw from 'twin.macro' ;
import Field from '@/components/elements/Field' ;
import SpinnerOverlay from '@/components/elements/SpinnerOverlay' ;
2021-09-16 20:59:22 +00:00
import { Form , Formik , FormikHelpers , useFormikContext } from 'formik' ;
2021-05-20 22:00:46 +00:00
import { ApplicationStore } from '@/state' ;
import { Actions , useStoreActions } from 'easy-peasy' ;
import Label from '@/components/elements/Label' ;
2021-09-16 20:59:22 +00:00
import { object } from 'yup' ;
2021-05-20 22:00:46 +00:00
2021-09-17 02:19:10 +00:00
function ServerStartupLineContainer ( { egg , server } : { egg : Egg | null ; server : Server } ) {
2021-09-16 22:46:41 +00:00
const { isSubmitting , setFieldValue } = useFormikContext ( ) ;
useEffect ( ( ) = > {
2021-09-17 02:19:10 +00:00
if ( egg === null ) {
return ;
}
2021-09-16 22:46:41 +00:00
if ( server . eggId === egg . id ) {
setFieldValue ( 'startup' , server . container . startup ) ;
return ;
}
// Whenever the egg is changed, set the server's startup command to the egg's default.
setFieldValue ( 'startup' , egg . startup ) ;
} , [ egg ] ) ;
2021-05-20 22:00:46 +00:00
return (
2021-09-13 05:50:12 +00:00
< AdminBox title = { 'Startup Command' } css = { tw ` relative w-full ` } >
2021-05-20 22:00:46 +00:00
< SpinnerOverlay visible = { isSubmitting } / >
2021-09-16 20:59:22 +00:00
< div css = { tw ` mb-6 ` } >
< Field
id = { 'startup' }
name = { 'startup' }
label = { 'Startup Command' }
type = { 'text' }
description = { 'Edit your server\'s startup command here. The following variables are available by default: {{SERVER_MEMORY}}, {{SERVER_IP}}, and {{SERVER_PORT}}.' }
/ >
< / div >
2021-09-13 05:50:12 +00:00
2021-09-16 20:59:22 +00:00
< div >
< Label > Default Startup Command < / Label >
2021-09-17 02:19:10 +00:00
< Input value = { egg ? . startup || '' } readOnly / >
2021-09-16 20:59:22 +00:00
< / div >
2021-05-20 22:00:46 +00:00
< / AdminBox >
) ;
2021-09-13 05:50:12 +00:00
}
2021-05-20 22:00:46 +00:00
2021-09-16 22:46:41 +00:00
function ServerServiceContainer ( { egg , setEgg , server } : { egg : Egg | null , setEgg : ( value : Egg | null ) = > void , server : Server } ) {
2021-05-20 22:00:46 +00:00
const { isSubmitting } = useFormikContext ( ) ;
2021-09-16 03:19:39 +00:00
const [ nestId , setNestId ] = useState < number | null > ( server . nestId ) ;
2021-05-20 22:00:46 +00:00
return (
< AdminBox title = { 'Service Configuration' } css = { tw ` relative w-full ` } >
< SpinnerOverlay visible = { isSubmitting } / >
2021-09-16 20:59:22 +00:00
< div css = { tw ` mb-6 ` } >
< NestSelect nestId = { nestId } setNestId = { setNestId } / >
< / div >
2021-09-13 05:50:12 +00:00
2021-09-16 20:59:22 +00:00
< div css = { tw ` mb-6 ` } >
< EggSelect nestId = { nestId } egg = { egg } setEgg = { setEgg } / >
< / div >
2021-09-13 05:50:12 +00:00
2021-09-16 20:59:22 +00:00
< div css = { tw ` bg-neutral-800 border border-neutral-900 shadow-inner p-4 rounded ` } >
< FormikSwitch
name = { 'skipScript' }
label = { 'Skip Egg Install Script' }
description = { 'SoonTM' }
/ >
< / div >
2021-05-20 22:00:46 +00:00
< / AdminBox >
) ;
2021-09-13 05:50:12 +00:00
}
2021-05-20 22:00:46 +00:00
2021-09-13 05:50:12 +00:00
function ServerImageContainer ( ) {
2021-05-20 22:00:46 +00:00
const { isSubmitting } = useFormikContext ( ) ;
return (
2021-09-13 05:50:12 +00:00
< AdminBox title = { 'Image Configuration' } css = { tw ` relative w-full ` } >
2021-05-20 22:00:46 +00:00
< SpinnerOverlay visible = { isSubmitting } / >
2021-09-16 20:59:22 +00:00
< div css = { tw ` md:w-full md:flex md:flex-col ` } >
< div >
< Field
id = { 'image' }
name = { 'image' }
label = { 'Docker Image' }
type = { 'text' }
/ >
2021-05-20 22:00:46 +00:00
< / div >
2021-09-16 20:59:22 +00:00
< / div >
2021-05-20 22:00:46 +00:00
< / AdminBox >
) ;
2021-09-13 05:50:12 +00:00
}
2021-05-20 22:00:46 +00:00
2021-09-16 03:19:39 +00:00
function ServerVariableContainer ( { variable , defaultValue } : { variable : EggVariable , defaultValue : string } ) {
2021-09-16 20:59:22 +00:00
const key = 'environment.' + variable . envVariable ;
const { isSubmitting , setFieldValue } = useFormikContext ( ) ;
2021-09-16 03:19:39 +00:00
useEffect ( ( ) = > {
2021-09-16 20:59:22 +00:00
setFieldValue ( key , defaultValue ) ;
} , [ variable , defaultValue ] ) ;
2021-09-16 03:19:39 +00:00
return (
2021-09-16 20:59:22 +00:00
< AdminBox css = { tw ` relative w-full ` } title = { < p css = { tw ` text-sm uppercase ` } > { variable . name } < / p > } >
< SpinnerOverlay visible = { isSubmitting } / >
< Field
id = { key }
name = { key }
type = { 'text' }
placeholder = { variable . defaultValue }
description = { variable . description }
/ >
2021-09-16 03:19:39 +00:00
< / AdminBox >
) ;
}
2021-09-17 02:19:10 +00:00
function ServerStartupForm ( { egg , setEgg , server } : { egg : Egg | null , setEgg : ( value : Egg | null ) = > void ; server : Server } ) {
2021-09-16 22:46:41 +00:00
const { isSubmitting , isValid } = useFormikContext ( ) ;
2021-09-16 20:59:22 +00:00
return (
< Form >
< div css = { tw ` flex flex-col ` } >
< div css = { tw ` flex flex-row mb-6 ` } >
2021-09-16 22:46:41 +00:00
< ServerStartupLineContainer
egg = { egg }
server = { server }
/ >
2021-09-16 20:59:22 +00:00
< / div >
< div css = { tw ` grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6 mb-6 ` } >
< div css = { tw ` flex ` } >
< ServerServiceContainer
egg = { egg }
setEgg = { setEgg }
2021-09-16 22:46:41 +00:00
server = { server }
2021-09-16 20:59:22 +00:00
/ >
< / div >
< div css = { tw ` flex ` } >
< ServerImageContainer / >
< / div >
< / div >
< div css = { tw ` grid grid-cols-1 md:grid-cols-2 gap-y-6 gap-x-8 ` } >
2021-09-17 02:19:10 +00:00
{ egg ? . relations . variables ? . map ( ( v , i ) = > (
2021-09-16 20:59:22 +00:00
< ServerVariableContainer
key = { i }
variable = { v }
2021-09-16 22:46:41 +00:00
defaultValue = { server . relations ? . variables . find ( v2 = > v . eggId === v2 . eggId && v . envVariable === v2 . envVariable ) ? . serverValue || v . defaultValue }
2021-09-16 20:59:22 +00:00
/ >
) ) }
< / div >
< div css = { tw ` bg-neutral-700 rounded shadow-md py-2 pr-6 mt-6 ` } >
< div css = { tw ` flex flex-row ` } >
< Button type = "submit" size = "small" css = { tw ` ml-auto ` } disabled = { isSubmitting || ! isValid } >
Save Changes
< / Button >
< / div >
< / div >
< / div >
< / Form >
) ;
}
2021-09-16 03:19:39 +00:00
export default function ServerStartupContainer ( { server } : { server : Server } ) {
2021-09-16 20:59:22 +00:00
const { clearFlashes , clearAndAddHttpError } = useStoreActions ( ( actions : Actions < ApplicationStore > ) = > actions . flashes ) ;
2021-05-20 22:00:46 +00:00
2021-09-16 03:19:39 +00:00
const [ egg , setEgg ] = useState < Egg | null > ( null ) ;
2021-09-15 17:09:54 +00:00
2021-09-16 20:59:22 +00:00
const setServer = Context . useStoreActions ( actions = > actions . setServer ) ;
2021-09-16 03:19:39 +00:00
useEffect ( ( ) = > {
getEgg ( server . eggId , [ 'variables' ] )
. then ( egg = > setEgg ( egg ) )
. catch ( error = > console . error ( error ) ) ;
} , [ ] ) ;
2021-09-16 20:59:22 +00:00
const submit = ( values : Values , { setSubmitting } : FormikHelpers < Values > ) = > {
2021-09-15 17:09:54 +00:00
clearFlashes ( 'server' ) ;
2021-09-16 20:59:22 +00:00
updateServerStartup ( server . id , values , ServerIncludes )
. then ( s = > {
setServer ( { . . . server , . . . s } ) ;
} )
. catch ( error = > {
console . error ( error ) ;
clearAndAddHttpError ( { key : 'server' , error } ) ;
} )
. then ( ( ) = > setSubmitting ( false ) ) ;
2021-09-15 17:09:54 +00:00
} ;
2021-05-20 22:00:46 +00:00
return (
< Formik
onSubmit = { submit }
initialValues = { {
2021-09-16 20:59:22 +00:00
startup : server.container.startup ,
// Don't ask.
2021-09-17 02:19:10 +00:00
environment : Object.fromEntries ( egg ? . relations . variables ? . map ( v = > [ v . envVariable , '' ] ) || [ ] ) ,
2021-09-13 05:50:12 +00:00
image : server.container.image ,
2021-09-16 20:59:22 +00:00
eggId : server.eggId ,
2021-09-13 05:50:12 +00:00
skipScripts : false ,
2021-05-20 22:00:46 +00:00
} }
2021-09-16 20:59:22 +00:00
validationSchema = { object ( ) . shape ( {
} ) }
2021-05-20 22:00:46 +00:00
>
2021-09-16 22:46:41 +00:00
< ServerStartupForm
egg = { egg }
setEgg = { setEgg }
server = { server }
/ >
2021-05-20 22:00:46 +00:00
< / Formik >
) ;
2021-09-13 05:50:12 +00:00
}