import { LanguageDescription } from '@codemirror/language'; import { json } from '@codemirror/lang-json'; import { faDocker } from '@fortawesome/free-brands-svg-icons'; import { faEgg, faFireAlt, faMicrochip, faTerminal } from '@fortawesome/free-solid-svg-icons'; import type { FormikHelpers } from 'formik'; import { Form, Formik, useFormikContext } from 'formik'; import { forwardRef, useImperativeHandle, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import tw from 'twin.macro'; import { object } from 'yup'; import { useEggFromRoute } from '@/api/admin/egg'; import updateEgg from '@/api/admin/eggs/updateEgg'; import AdminBox from '@/components/admin/AdminBox'; import EggDeleteButton from '@/components/admin/nests/eggs/EggDeleteButton'; import EggExportButton from '@/components/admin/nests/eggs/EggExportButton'; import { Button } from '@/components/elements/button'; import { Editor } from '@/components/elements/editor'; import Field, { TextareaField } from '@/components/elements/Field'; import Input from '@/components/elements/Input'; import Label from '@/components/elements/Label'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; import useFlash from '@/plugins/useFlash'; export function EggInformationContainer() { const { isSubmitting } = useFormikContext(); return ( ); } function EggDetailsContainer() { const { data: egg } = useEggFromRoute(); if (!egg) { return null; } return (
); } export function EggStartupContainer({ className }: { className?: string }) { const { isSubmitting } = useFormikContext(); return ( ); } export function EggImageContainer() { const { isSubmitting } = useFormikContext(); return ( ); } export function EggLifecycleContainer() { const { isSubmitting } = useFormikContext(); return ( ); } interface EggProcessContainerProps { className?: string; } export interface EggProcessContainerRef { getStartupConfiguration: () => Promise; getFilesConfiguration: () => Promise; } export const EggProcessContainer = forwardRef(function EggProcessContainer( { className }, ref, ) { const { isSubmitting, values } = useFormikContext(); let fetchStartupConfiguration: (() => Promise) | null = null; let fetchFilesConfiguration: (() => Promise) | null = null; useImperativeHandle(ref, () => ({ getStartupConfiguration: async () => { if (fetchStartupConfiguration === null) { return new Promise(resolve => resolve(null)); } return await fetchStartupConfiguration(); }, getFilesConfiguration: async () => { if (fetchFilesConfiguration === null) { return new Promise(resolve => resolve(null)); } return await fetchFilesConfiguration(); }, })); return (
{ fetchStartupConfiguration = value; }} language={LanguageDescription.of({ name: 'json', support: json() })} />
{ fetchFilesConfiguration = value; }} language={LanguageDescription.of({ name: 'json', support: json() })} />
); }); interface Values { name: string; description: string; startup: string; dockerImages: string; configStop: string; configStartup: string; configFiles: string; } export default function EggSettingsContainer() { const navigate = useNavigate(); const ref = useRef(); const { clearFlashes, clearAndAddHttpError } = useFlash(); const { data: egg } = useEggFromRoute(); if (!egg) { return null; } const submit = async (values: Values, { setSubmitting }: FormikHelpers) => { clearFlashes('egg'); values.configStartup = (await ref.current?.getStartupConfiguration()) ?? ''; values.configFiles = (await ref.current?.getFilesConfiguration()) ?? ''; const dockerImages: Record = {}; for (const v of values.dockerImages.split('\n')) { const parts = v.trim().split('|'); const image = parts[0] ?? ''; const alias = parts[1] ?? image; dockerImages[alias] = image; } updateEgg(egg.id, { ...values, dockerImages, }) .catch(error => { console.error(error); clearAndAddHttpError({ key: 'egg', error }); }) .then(() => setSubmitting(false)); }; return ( { return `${egg.dockerImages[key]}|${key}`; }) .join('\n'), configStop: egg.configStop || '', configStartup: JSON.stringify(egg.configStartup, null, '\t') || '', configFiles: JSON.stringify(egg.configFiles, null, '\t') || '', }} validationSchema={object().shape({})} > {({ isSubmitting, isValid }) => (
navigate('/admin/nests')} />
)}
); }