chore(template/git): sync frontend code from ee (#11344)

pull/11391/head
Oscar Zhou 2024-03-18 08:55:16 +13:00 committed by GitHub
parent 73307e164b
commit bb02c69d14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 77 additions and 16 deletions

View File

@ -345,6 +345,7 @@ export default class CreateEdgeStackViewController {
RepositoryUsername: this.formValues.RepositoryUsername, RepositoryUsername: this.formValues.RepositoryUsername,
RepositoryPassword: this.formValues.RepositoryPassword, RepositoryPassword: this.formValues.RepositoryPassword,
TLSSkipVerify: this.formValues.TLSSkipVerify, TLSSkipVerify: this.formValues.TLSSkipVerify,
CreatedFromCustomTemplateID: this.state.templateValues.template.Id,
}; };
return this.EdgeStackService.createStackFromGitRepository( return this.EdgeStackService.createStackFromGitRepository(
{ {

View File

@ -35,6 +35,7 @@
on-change="($ctrl.onChangeFormValues)" on-change="($ctrl.onChangeFormValues)"
base-webhook-url="{{ $ctrl.state.baseWebhookUrl }}" base-webhook-url="{{ $ctrl.state.baseWebhookUrl }}"
webhook-id="{{ $ctrl.state.webhookId }}" webhook-id="{{ $ctrl.state.webhookId }}"
created-from-custom-template-id="($ctrl.state.templateValues.type === 'custom' ? $ctrl.state.templateValues.template.Id : 0)"
docs-links docs-links
></git-form> ></git-form>
</div> </div>

View File

@ -65,7 +65,7 @@ export default class GitFormAuthFieldsetController {
); );
this.errors = await validateForm<GitAuthModel>( this.errors = await validateForm<GitAuthModel>(
() => gitAuthValidation(this.gitCredentials, isAuthEdit), () => gitAuthValidation(this.gitCredentials, isAuthEdit, false),
value value
); );
if (this.errors && Object.keys(this.errors).length > 0) { if (this.errors && Object.keys(this.errors).length > 0) {

View File

@ -24,6 +24,8 @@ export default class GitFormController {
onChange?: (value: GitFormModel) => void; onChange?: (value: GitFormModel) => void;
createdFromCustomTemplateId?: number;
/* @ngInject */ /* @ngInject */
constructor( constructor(
$async: <T>(fn: () => Promise<T>) => Promise<T>, $async: <T>(fn: () => Promise<T>) => Promise<T>,
@ -47,15 +49,26 @@ export default class GitFormController {
...newValues, ...newValues,
}; };
this.onChange?.(value); this.onChange?.(value);
await this.runGitFormValidation(value);
const isCreatedFromCustomTemplate =
!!this.createdFromCustomTemplateId &&
this.createdFromCustomTemplateId > 0;
await this.runGitFormValidation(value, isCreatedFromCustomTemplate);
} }
async runGitFormValidation(value: GitFormModel) { async runGitFormValidation(
value: GitFormModel,
isCreatedFromCustomTemplate: boolean
) {
return this.$async(async () => { return this.$async(async () => {
this.errors = {}; this.errors = {};
this.gitForm?.$setValidity('gitForm', true, this.gitForm); this.gitForm?.$setValidity('gitForm', true, this.gitForm);
this.errors = await validateGitForm(this.gitCredentials, value); this.errors = await validateGitForm(
this.gitCredentials,
value,
isCreatedFromCustomTemplate
);
if (this.errors && Object.keys(this.errors).length > 0) { if (this.errors && Object.keys(this.errors).length > 0) {
this.gitForm?.$setValidity('gitForm', false, this.gitForm); this.gitForm?.$setValidity('gitForm', false, this.gitForm);
} }
@ -82,6 +95,9 @@ export default class GitFormController {
throw new Error('GitFormController: value is required'); throw new Error('GitFormController: value is required');
} }
await this.runGitFormValidation(this.value); const isCreatedFromCustomTemplate =
!!this.createdFromCustomTemplateId &&
this.createdFromCustomTemplateId > 0;
await this.runGitFormValidation(this.value, isCreatedFromCustomTemplate);
} }
} }

View File

@ -17,6 +17,7 @@ export const gitForm: IComponentOptions = {
base-webhook-url="$ctrl.baseWebhookUrl" base-webhook-url="$ctrl.baseWebhookUrl"
webhook-id="$ctrl.webhookId" webhook-id="$ctrl.webhookId"
webhooks-docs="$ctrl.webhooksDocs" webhooks-docs="$ctrl.webhooksDocs"
created-from-custom-template-id="$ctrl.createdFromCustomTemplateId"
errors="$ctrl.errors"> errors="$ctrl.errors">
</react-git-form> </react-git-form>
</ng-form>`, </ng-form>`,
@ -32,6 +33,7 @@ export const gitForm: IComponentOptions = {
isAuthExplanationVisible: '<', isAuthExplanationVisible: '<',
webhookId: '@', webhookId: '@',
webhooksDocs: '@', webhooksDocs: '@',
createdFromCustomTemplateId: '<',
}, },
controller, controller,
}; };

View File

@ -28,6 +28,7 @@ export const gitFormModule = angular
'baseWebhookUrl', 'baseWebhookUrl',
'webhookId', 'webhookId',
'webhooksDocs', 'webhooksDocs',
'createdFromCustomTemplateId',
]) ])
) )
.component( .component(
@ -69,6 +70,7 @@ export const gitFormModule = angular
'model', 'model',
'onChange', 'onChange',
'stackId', 'stackId',
'createdFromCustomTemplateId',
'value', 'value',
'isUrlValid', 'isUrlValid',
]) ])

View File

@ -147,7 +147,8 @@ export function AuthFieldset({
export function gitAuthValidation( export function gitAuthValidation(
gitCredentials: Array<GitCredential>, gitCredentials: Array<GitCredential>,
isAuthEdit: boolean isAuthEdit: boolean,
isCreatedFromCustomTemplate: boolean
): SchemaOf<GitAuthModel> { ): SchemaOf<GitAuthModel> {
return object({ return object({
RepositoryAuthentication: boolean().default(false), RepositoryAuthentication: boolean().default(false),
@ -160,7 +161,8 @@ export function gitAuthValidation(
.default(''), .default(''),
RepositoryPassword: string() RepositoryPassword: string()
.when(['RepositoryAuthentication', 'RepositoryGitCredentialID'], { .when(['RepositoryAuthentication', 'RepositoryGitCredentialID'], {
is: (auth: boolean, id: number) => auth && !id && !isAuthEdit, is: (auth: boolean, id: number) =>
auth && !id && !isAuthEdit && !isCreatedFromCustomTemplate,
then: string().required('Password is required'), then: string().required('Password is required'),
}) })
.default(''), .default(''),

View File

@ -16,6 +16,7 @@ interface Props {
isCompose: boolean; isCompose: boolean;
model: GitFormModel; model: GitFormModel;
isDockerStandalone: boolean; isDockerStandalone: boolean;
createdFromCustomTemplateId?: number;
} }
export function ComposePathField({ export function ComposePathField({
@ -25,6 +26,7 @@ export function ComposePathField({
model, model,
isDockerStandalone, isDockerStandalone,
errors, errors,
createdFromCustomTemplateId,
}: Props) { }: Props) {
const [inputValue, updateInputValue] = useStateWrapper(value, onChange); const [inputValue, updateInputValue] = useStateWrapper(value, onChange);
@ -64,6 +66,7 @@ export function ComposePathField({
placeholder={isCompose ? 'docker-compose.yml' : 'manifest.yml'} placeholder={isCompose ? 'docker-compose.yml' : 'manifest.yml'}
model={model} model={model}
inputId="stack_repository_path" inputId="stack_repository_path"
createdFromCustomTemplateId={createdFromCustomTemplateId}
/> />
) : ( ) : (
<Input <Input

View File

@ -13,6 +13,7 @@ export function PathSelector({
dirOnly, dirOnly,
readOnly, readOnly,
inputId, inputId,
createdFromCustomTemplateId,
}: { }: {
value: string; value: string;
onChange(value: string): void; onChange(value: string): void;
@ -21,6 +22,7 @@ export function PathSelector({
dirOnly?: boolean; dirOnly?: boolean;
readOnly?: boolean; readOnly?: boolean;
inputId: string; inputId: string;
createdFromCustomTemplateId?: number;
}) { }) {
const creds = getAuthentication(model); const creds = getAuthentication(model);
const payload = { const payload = {
@ -29,6 +31,7 @@ export function PathSelector({
reference: model.RepositoryReferenceName, reference: model.RepositoryReferenceName,
tlsSkipVerify: model.TLSSkipVerify, tlsSkipVerify: model.TLSSkipVerify,
dirOnly, dirOnly,
createdFromCustomTemplateId,
...creds, ...creds,
}; };
const enabled = Boolean( const enabled = Boolean(

View File

@ -73,7 +73,7 @@ export function Primary({
return ( return (
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
validationSchema={() => buildGitValidationSchema([])} validationSchema={() => buildGitValidationSchema([], false)}
onSubmit={() => {}} onSubmit={() => {}}
> >
{({ values, errors, setValues }) => ( {({ values, errors, setValues }) => (

View File

@ -34,6 +34,7 @@ interface Props {
baseWebhookUrl?: string; baseWebhookUrl?: string;
webhookId?: string; webhookId?: string;
webhooksDocs?: string; webhooksDocs?: string;
createdFromCustomTemplateId?: number;
} }
export function GitForm({ export function GitForm({
@ -49,6 +50,7 @@ export function GitForm({
baseWebhookUrl, baseWebhookUrl,
webhookId, webhookId,
webhooksDocs, webhooksDocs,
createdFromCustomTemplateId,
}: Props) { }: Props) {
const [value, setValue] = useState(initialValue); // TODO: remove this state when form is not inside angularjs const [value, setValue] = useState(initialValue); // TODO: remove this state when form is not inside angularjs
const webhooksDocsUrl = useDocsUrl(webhooksDocs); const webhooksDocsUrl = useDocsUrl(webhooksDocs);
@ -69,6 +71,7 @@ export function GitForm({
handleChange({ RepositoryURLValid: value }) handleChange({ RepositoryURLValid: value })
} }
model={value} model={value}
createdFromCustomTemplateId={createdFromCustomTemplateId}
errors={errors.RepositoryURL} errors={errors.RepositoryURL}
/> />
@ -78,6 +81,7 @@ export function GitForm({
model={value} model={value}
error={errors.RepositoryReferenceName} error={errors.RepositoryReferenceName}
isUrlValid={value.RepositoryURLValid} isUrlValid={value.RepositoryURLValid}
createdFromCustomTemplateId={createdFromCustomTemplateId}
/> />
<ComposePathField <ComposePathField
@ -89,6 +93,7 @@ export function GitForm({
model={value} model={value}
isDockerStandalone={isDockerStandalone} isDockerStandalone={isDockerStandalone}
errors={errors.ComposeFilePathInRepository} errors={errors.ComposeFilePathInRepository}
createdFromCustomTemplateId={createdFromCustomTemplateId}
/> />
{isAdditionalFilesFieldVisible && ( {isAdditionalFilesFieldVisible && (
@ -137,16 +142,18 @@ export function GitForm({
export async function validateGitForm( export async function validateGitForm(
gitCredentials: Array<GitCredential>, gitCredentials: Array<GitCredential>,
formValues: GitFormModel formValues: GitFormModel,
isCreatedFromCustomTemplate: boolean
) { ) {
return validateForm<GitFormModel>( return validateForm<GitFormModel>(
() => buildGitValidationSchema(gitCredentials), () => buildGitValidationSchema(gitCredentials, isCreatedFromCustomTemplate),
formValues formValues
); );
} }
export function buildGitValidationSchema( export function buildGitValidationSchema(
gitCredentials: Array<GitCredential> gitCredentials: Array<GitCredential>,
isCreatedFromCustomTemplate: boolean
): SchemaOf<GitFormModel> { ): SchemaOf<GitFormModel> {
return object({ return object({
RepositoryURL: string() RepositoryURL: string()
@ -171,5 +178,7 @@ export function buildGitValidationSchema(
RepositoryURLValid: boolean().default(false), RepositoryURLValid: boolean().default(false),
AutoUpdate: autoUpdateValidation().nullable(), AutoUpdate: autoUpdateValidation().nullable(),
TLSSkipVerify: boolean().default(false), TLSSkipVerify: boolean().default(false),
}).concat(gitAuthValidation(gitCredentials, false)) as SchemaOf<GitFormModel>; }).concat(
gitAuthValidation(gitCredentials, false, isCreatedFromCustomTemplate)
) as SchemaOf<GitFormModel>;
} }

View File

@ -26,6 +26,7 @@ interface Props {
onChange(value: string): void; onChange(value: string): void;
onChangeRepositoryValid(value: boolean): void; onChangeRepositoryValid(value: boolean): void;
model: GitFormModel; model: GitFormModel;
createdFromCustomTemplateId?: number;
errors?: string; errors?: string;
} }
@ -34,6 +35,7 @@ export function GitFormUrlField({
onChange, onChange,
onChangeRepositoryValid, onChangeRepositoryValid,
model, model,
createdFromCustomTemplateId,
errors, errors,
}: Props) { }: Props) {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
@ -42,7 +44,12 @@ export function GitFormUrlField({
const [force, setForce] = useState(false); const [force, setForce] = useState(false);
const repoStatusQuery = useCheckRepo( const repoStatusQuery = useCheckRepo(
value, value,
{ creds, force, tlsSkipVerify: model.TLSSkipVerify }, {
creds,
force,
tlsSkipVerify: model.TLSSkipVerify,
createdFromCustomTemplateId,
},
{ {
onSettled(isValid) { onSettled(isValid) {
onChangeRepositoryValid(!!isValid); onChangeRepositoryValid(!!isValid);

View File

@ -20,6 +20,7 @@ interface Props {
error?: string; error?: string;
isUrlValid?: boolean; isUrlValid?: boolean;
stackId?: StackId; stackId?: StackId;
createdFromCustomTemplateId?: number;
} }
export function RefField({ export function RefField({
@ -29,6 +30,7 @@ export function RefField({
error, error,
isUrlValid, isUrlValid,
stackId, stackId,
createdFromCustomTemplateId,
}: Props) { }: Props) {
const [inputValue, updateInputValue] = useStateWrapper(value, onChange); const [inputValue, updateInputValue] = useStateWrapper(value, onChange);
const inputId = 'repository-reference-field'; const inputId = 'repository-reference-field';
@ -51,6 +53,7 @@ export function RefField({
model={model} model={model}
isUrlValid={isUrlValid} isUrlValid={isUrlValid}
stackId={stackId} stackId={stackId}
createdFromCustomTemplateId={createdFromCustomTemplateId}
/> />
</Wrapper> </Wrapper>
) : ( ) : (

View File

@ -13,11 +13,13 @@ export function RefSelector({
onChange, onChange,
isUrlValid, isUrlValid,
stackId, stackId,
createdFromCustomTemplateId,
inputId, inputId,
}: { }: {
model: RefFieldModel; model: RefFieldModel;
value: string; value: string;
stackId?: StackId; stackId?: StackId;
createdFromCustomTemplateId?: number;
onChange: (value: string) => void; onChange: (value: string) => void;
isUrlValid?: boolean; isUrlValid?: boolean;
inputId: string; inputId: string;
@ -26,6 +28,7 @@ export function RefSelector({
const payload = { const payload = {
repository: model.RepositoryURL, repository: model.RepositoryURL,
stackId, stackId,
createdFromCustomTemplateId,
tlsSkipVerify: model.TLSSkipVerify, tlsSkipVerify: model.TLSSkipVerify,
...creds, ...creds,
}; };

View File

@ -15,6 +15,7 @@ interface CheckRepoOptions {
creds?: Creds; creds?: Creds;
force?: boolean; force?: boolean;
tlsSkipVerify?: boolean; tlsSkipVerify?: boolean;
createdFromCustomTemplateId?: number;
} }
export function useCheckRepo( export function useCheckRepo(
@ -43,7 +44,12 @@ export async function checkRepo(
try { try {
await axios.post<string[]>( await axios.post<string[]>(
'/gitops/repo/refs', '/gitops/repo/refs',
{ repository, tlsSkipVerify: options.tlsSkipVerify, ...options.creds }, {
repository,
tlsSkipVerify: options.tlsSkipVerify,
createdFromCustomTemplateId: options.createdFromCustomTemplateId,
...options.creds,
},
force ? { params: { force } } : {} force ? { params: { force } } : {}
); );
return true; return true;

View File

@ -6,6 +6,7 @@ interface RefsPayload {
repository: string; repository: string;
username?: string; username?: string;
password?: string; password?: string;
createdFromCustomTemplateID?: number;
tlsSkipVerify?: boolean; tlsSkipVerify?: boolean;
} }

View File

@ -9,6 +9,7 @@ interface SearchPayload {
username?: string; username?: string;
password?: string; password?: string;
tlsSkipVerify?: boolean; tlsSkipVerify?: boolean;
createdFromCustomTemplateId?: number;
} }
export function useSearch(payload: SearchPayload, enabled: boolean) { export function useSearch(payload: SearchPayload, enabled: boolean) {

View File

@ -57,7 +57,8 @@ export function useValidation({
}), }),
Git: mixed().when('Method', { Git: mixed().when('Method', {
is: git.value, is: git.value,
then: () => buildGitValidationSchema(gitCredentialsQuery.data || []), then: () =>
buildGitValidationSchema(gitCredentialsQuery.data || [], false),
}), }),
Variables: variablesValidation(), Variables: variablesValidation(),
EdgeSettings: viewType === 'edge' ? edgeFieldsetValidation() : mixed(), EdgeSettings: viewType === 'edge' ? edgeFieldsetValidation() : mixed(),

View File

@ -47,7 +47,7 @@ export function useValidation({
FileContent: string().required('Template is required.'), FileContent: string().required('Template is required.'),
Git: isGit Git: isGit
? buildGitValidationSchema(gitCredentialsQuery.data || []) ? buildGitValidationSchema(gitCredentialsQuery.data || [], false)
: mixed(), : mixed(),
Variables: variablesValidation(), Variables: variablesValidation(),
EdgeSettings: viewType === 'edge' ? edgeFieldsetValidation() : mixed(), EdgeSettings: viewType === 'edge' ? edgeFieldsetValidation() : mixed(),