import { FormikErrors, useFormikContext } from 'formik'; import { SetStateAction } from 'react'; import { GitForm } from '@/react/portainer/gitops/GitForm'; import { baseEdgeStackWebhookUrl } from '@/portainer/helpers/webhookHelper'; import { RelativePathFieldset } from '@/react/portainer/gitops/RelativePathFieldset/RelativePathFieldset'; import { applySetStateAction } from '@/react-tools/apply-set-state-action'; import { isBE } from '@/react/portainer/feature-flags/feature-flags.service'; import { BoxSelector } from '@@/BoxSelector'; import { FormSection } from '@@/form-components/FormSection'; import { editor, git, edgeStackTemplate, upload, } from '@@/BoxSelector/common-options/build-methods'; import { FileUploadForm } from '@@/form-components/FileUpload'; import { TemplateFieldset } from './TemplateFieldset/TemplateFieldset'; import { useRenderCustomTemplate } from './useRenderCustomTemplate'; import { DockerFormValues } from './types'; import { DockerContentField } from './DockerContentField'; import { useRenderAppTemplate } from './useRenderAppTemplate'; const buildMethods = [editor, upload, git, edgeStackTemplate] as const; interface Props { webhookId: string; onChangeTemplate: (change: { type: 'app' | 'custom' | undefined; id: number | undefined; }) => void; } export function DockerComposeForm({ webhookId, onChangeTemplate }: Props) { const { errors, values, setValues } = useFormikContext(); const { method } = values; return ( <> handleChange({ method: value })} value={method} radioName="method" slim /> {method === edgeStackTemplate.value && ( <> { const templateValues = applySetStateAction( templateAction, values.templateValues ); onChangeTemplate({ id: templateValues.templateId, type: templateValues.type, }); setValues((values) => ({ ...values, templateValues, })); }} errors={errors?.templateValues} /> {values.templateValues.type === 'app' && ( )} {values.templateValues.type === 'custom' && ( )} )} {method === editor.value && ( handleChange({ fileContent: value })} error={errors?.fileContent} /> )} {method === upload.value && ( handleChange({ file: File })} required description="You can upload a Compose file from your computer." data-cy="stack-creation-file-upload" /> )} {method === git.value && ( <> setValues((values) => ({ ...values, git: { ...values.git, ...gitValues, }, })) } baseWebhookUrl={baseEdgeStackWebhookUrl()} webhookId={webhookId} /> {isBE && ( setValues((values) => ({ ...values, relativePath: { ...values.relativePath, ...relativePath, }, })) } /> )} )} ); function handleChange(newValues: Partial) { setValues((values) => ({ ...values, ...newValues, })); } } type TemplateContentFieldProps = { values: DockerFormValues; handleChange: (newValues: Partial) => void; errors?: FormikErrors; setValues: (values: SetStateAction) => void; }; function AppTemplateContentField({ values, handleChange, errors, setValues, }: TemplateContentFieldProps) { const { isInitialLoading } = useRenderAppTemplate( values.templateValues, setValues ); return ( handleChange({ fileContent: value })} error={errors?.fileContent} isLoading={isInitialLoading} /> ); } function CustomTemplateContentField({ values, handleChange, errors, setValues, }: TemplateContentFieldProps) { const { customTemplate, isInitialLoading } = useRenderCustomTemplate( values.templateValues, setValues ); return ( handleChange({ fileContent: value })} error={errors?.fileContent} readonly={!!customTemplate?.GitConfig} isLoading={isInitialLoading} /> ); }