import { useState } from 'react'; import { array, number, object, SchemaOf, string } from 'yup'; import { FormikErrors } from 'formik'; import { ComposePathField } from '@/react/portainer/gitops/ComposePathField'; import { RefField } from '@/react/portainer/gitops/RefField'; import { DeployMethod, GitFormModel } from '@/react/portainer/gitops/types'; import { TimeWindowDisplay } from '@/react/portainer/gitops/TimeWindowDisplay'; import { GitSourceSelector } from '@/react/portainer/gitops/sources/GitSourceSelector'; import { FormSection } from '@@/form-components/FormSection'; import { validateForm } from '@@/form-components/validate-form'; import { AdditionalFileField } from './AdditionalFilesField'; import { AutoUpdateFieldset } from './AutoUpdateFieldset'; import { autoUpdateValidation } from './AutoUpdateFieldset/validation'; import { refFieldValidation } from './RefField/RefField'; interface Props { value: GitFormModel; onChange: (value: Partial) => void; environmentType?: 'DOCKER' | 'KUBERNETES' | undefined; deployMethod?: DeployMethod; isDockerStandalone?: boolean; isAdditionalFilesFieldVisible?: boolean; isForcePullVisible?: boolean; errors?: FormikErrors; baseWebhookUrl?: string; webhookId?: string; webhooksDocs?: string; isAutoUpdateVisible?: boolean; } export function GitForm({ value: initialValue, onChange, environmentType = 'DOCKER', deployMethod = 'compose', isDockerStandalone = false, isAdditionalFilesFieldVisible, isForcePullVisible, errors = {}, baseWebhookUrl, webhookId, webhooksDocs, isAutoUpdateVisible = true, }: Props) { const [value, setValue] = useState(initialValue); // TODO: remove this state when form is not inside angularjs return ( handleChange({ SourceId: source?.id, RepositoryReferenceName: initialValue.RepositoryReferenceName, ComposeFilePathInRepository: initialValue.ComposeFilePathInRepository, }) } error={errors.SourceId} /> handleChange({ RepositoryReferenceName: value })} sourceId={value.SourceId} error={errors.RepositoryReferenceName} /> handleChange({ ComposeFilePathInRepository: value || undefined }) } isCompose={deployMethod === 'compose'} model={value} isDockerStandalone={isDockerStandalone} errors={errors.ComposeFilePathInRepository} /> {isAdditionalFilesFieldVisible && ( handleChange({ AdditionalFiles: value })} errors={errors.AdditionalFiles} /> )} {isAutoUpdateVisible && value.AutoUpdate && ( handleChange({ AutoUpdate: value })} isForcePullVisible={isForcePullVisible} errors={errors.AutoUpdate as FormikErrors} webhooksDocs={webhooksDocs} /> )} ); function handleChange(partialValue: Partial) { onChange(partialValue); setValue((value) => ({ ...value, ...partialValue })); } } export async function validateGitForm( formValues: GitFormModel, deployMethod: DeployMethod = 'compose' ) { return validateForm( () => buildGitValidationSchema(deployMethod), formValues ); } export function buildGitValidationSchema( deployMethod: DeployMethod ): SchemaOf { return object({ RepositoryURL: string().optional(), RepositoryReferenceName: refFieldValidation(), ComposeFilePathInRepository: string().required( deployMethod === 'compose' ? 'Compose file path is required' : 'Manifest file path is required' ), AdditionalFiles: array(string().required('Path is required')).default([]), AutoUpdate: autoUpdateValidation().nullable(), SourceId: number() .min(1, 'Source is required') .required('Source is required'), }) as SchemaOf; }