import React, { useCallback, useEffect, useState } from 'react'; import TitledGreyBox from '@/components/elements/TitledGreyBox'; import tw from 'twin.macro'; import VariableBox from '@/components/server/startup/VariableBox'; import ServerContentBlock from '@/components/elements/ServerContentBlock'; import getServerStartup from '@/api/swr/getServerStartup'; import Spinner from '@/components/elements/Spinner'; import { ServerError } from '@/components/elements/ScreenBlock'; import { httpErrorToHuman } from '@/api/http'; import { ServerContext } from '@/state/server'; import { useDeepCompareEffect } from '@/plugins/useDeepCompareEffect'; import Select from '@/components/elements/Select'; import isEqual from 'react-fast-compare'; import Input from '@/components/elements/Input'; import setSelectedDockerImage from '@/api/server/setSelectedDockerImage'; import InputSpinner from '@/components/elements/InputSpinner'; import useFlash from '@/plugins/useFlash'; const StartupContainer = () => { const [ loading, setLoading ] = useState(false); const { clearFlashes, clearAndAddHttpError } = useFlash(); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); const variables = ServerContext.useStoreState(({ server }) => ({ variables: server.data!.variables, invocation: server.data!.invocation, dockerImage: server.data!.dockerImage, }), isEqual); const { data, error, isValidating, mutate } = getServerStartup(uuid, { ...variables, dockerImages: { [variables.dockerImage]: variables.dockerImage }, }); const setServerFromState = ServerContext.useStoreActions(actions => actions.server.setServerFromState); const isCustomImage = data && !Object.values(data.dockerImages).map(v => v.toLowerCase()).includes(variables.dockerImage.toLowerCase()); useEffect(() => { // Since we're passing in initial data this will not trigger on mount automatically. We // want to always fetch fresh information from the API however when we're loading the startup // information. mutate(); }, []); useDeepCompareEffect(() => { if (!data) return; setServerFromState(s => ({ ...s, invocation: data.invocation, variables: data.variables, })); }, [ data ]); const updateSelectedDockerImage = useCallback((v: React.ChangeEvent) => { setLoading(true); clearFlashes('startup:image'); const image = v.currentTarget.value; setSelectedDockerImage(uuid, image) .then(() => setServerFromState(s => ({ ...s, dockerImage: image }))) .catch(error => { console.error(error); clearAndAddHttpError({ key: 'startup:image', error }); }) .then(() => setLoading(false)); }, [ uuid ]); return ( !data ? (!error || (error && isValidating)) ? : mutate()} /> :

{data.invocation}

{Object.keys(data.dockerImages).length > 1 && !isCustomImage ? <>

This is an advanced feature allowing you to select a Docker image to use when running this server instance.

: <> {isCustomImage &&

This {'server\'s'} Docker image has been manually set by an administrator and cannot be changed through this UI.

} }

Variables

{data.variables.map(variable => )}
); }; export default StartupContainer;