You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
portainer/app/react/edge/edge-stacks/CreateView/DockerComposeForm.tsx

154 lines
4.5 KiB

import { useFormikContext } from 'formik';
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 { 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;
export function DockerComposeForm({
webhookId,
onChangeTemplate,
}: {
webhookId: string;
onChangeTemplate: ({
type,
id,
}: {
type: 'app' | 'custom' | undefined;
id: number | undefined;
}) => void;
}) {
const { errors, values, setValues } = useFormikContext<DockerFormValues>();
const { method } = values;
const { customTemplate, isInitialLoading: isCustomTemplateLoading } =
useRenderCustomTemplate(values.templateValues, setValues);
const { appTemplate, isInitialLoading: isAppTemplateLoading } =
useRenderAppTemplate(values.templateValues, setValues);
const isTemplate =
method === edgeStackTemplate.value && (customTemplate || appTemplate);
const isTemplateLoading = isCustomTemplateLoading || isAppTemplateLoading;
return (
<>
<FormSection title="Build Method">
<BoxSelector
options={buildMethods}
onChange={(value) => handleChange({ method: value })}
value={method}
radioName="method"
slim
/>
</FormSection>
{method === edgeStackTemplate.value && (
<TemplateFieldset
values={values.templateValues}
setValues={(templateAction) =>
setValues((values) => {
const templateValues = applySetStateAction(
templateAction,
values.templateValues
);
onChangeTemplate({
id: templateValues.templateId,
type: templateValues.type,
});
return {
...values,
templateValues,
};
})
}
errors={errors?.templateValues}
isLoadingValues={isTemplateLoading}
/>
)}
{(method === editor.value || isTemplate) && !isTemplateLoading && (
<DockerContentField
value={values.fileContent}
onChange={(value) => handleChange({ fileContent: value })}
readonly={
method === edgeStackTemplate.value && !!customTemplate?.GitConfig
}
error={errors?.fileContent}
/>
)}
{method === upload.value && (
<FileUploadForm
value={values.file}
onChange={(File) => handleChange({ file: File })}
required
description="You can upload a Compose file from your computer."
data-cy="stack-creation-file-upload"
/>
)}
{method === git.value && (
<>
<GitForm
errors={errors?.git}
value={values.git}
onChange={(gitValues) =>
setValues((values) => ({
...values,
git: {
...values.git,
...gitValues,
},
}))
}
baseWebhookUrl={baseEdgeStackWebhookUrl()}
webhookId={webhookId}
/>
<FormSection title="Advanced configurations">
<RelativePathFieldset
values={values.relativePath}
gitModel={values.git}
onChange={(relativePath) =>
setValues((values) => ({
...values,
relativePath: {
...values.relativePath,
...relativePath,
},
}))
}
/>
</FormSection>
</>
)}
</>
);
function handleChange(newValues: Partial<DockerFormValues>) {
setValues((values) => ({
...values,
...newValues,
}));
}
}