github.com/argoproj/argo-cd/v2@v2.10.9/ui/src/app/applications/components/application-retry-options/application-retry-options.tsx (about)

     1  import * as React from 'react';
     2  import {FormApi, NestedForm, Text, Form} from 'react-form';
     3  import {Checkbox, FormField} from 'argo-ui';
     4  import {omit} from 'lodash-es';
     5  import {NumberField} from '../../../shared/components';
     6  import * as models from '../../../shared/models';
     7  
     8  import './application-retry-options.scss';
     9  
    10  const durationRegex = /^([\d\.]+[HMS])+$/i;
    11  const durationRegexError = 'Should be 1h10m10s/10h10m/10m/10s';
    12  
    13  const onlyPositiveValidation = {
    14      min: '1',
    15      step: '1'
    16  };
    17  
    18  function buildFormItem(label: string, propertyPath: string, component: React.ComponentType, formApi: FormApi, componentProps?: Record<string, any>) {
    19      return <FormField formApi={formApi} label={label} field={propertyPath} component={component} componentProps={componentProps} />;
    20  }
    21  
    22  const retryOptions: Array<(formApi: FormApi) => React.ReactNode> = [
    23      formApi => buildFormItem('Limit', 'limit', NumberField, formApi, onlyPositiveValidation),
    24      formApi => buildFormItem('Duration', 'backoff.duration', Text, formApi),
    25      formApi => buildFormItem('Max Duration', 'backoff.maxDuration', Text, formApi),
    26      formApi => buildFormItem('Factor', 'backoff.factor', NumberField, formApi, onlyPositiveValidation)
    27  ];
    28  
    29  const defaultInitialValues = {
    30      limit: 2,
    31      backoff: {
    32          duration: '5s',
    33          maxDuration: '3m0s',
    34          factor: 2
    35      }
    36  };
    37  
    38  export const ApplicationRetryForm = ({initValues, field = 'retryStrategy'}: {initValues?: models.RetryStrategy; field: string}) => {
    39      return (
    40          <NestedForm field={field}>
    41              <Form
    42                  defaultValues={{
    43                      ...defaultInitialValues,
    44                      ...initValues
    45                  }}
    46                  validateError={values => {
    47                      const backoff = values.backoff || {};
    48  
    49                      if (!values) {
    50                          return {};
    51                      }
    52  
    53                      return {
    54                          'limit': !values.limit && values.hasOwnProperty('limit') && 'Limit is required',
    55  
    56                          'backoff.duration':
    57                              backoff.hasOwnProperty('duration') && ((!backoff.duration && 'Duration is required') || (!durationRegex.test(backoff.duration) && durationRegexError)),
    58  
    59                          'backoff.maxDuration':
    60                              backoff.hasOwnProperty('maxDuration') &&
    61                              ((!backoff.maxDuration && 'Max Duration is required') || (!durationRegex.test(backoff.maxDuration) && durationRegexError)),
    62  
    63                          'backoff.factor': backoff.hasOwnProperty('factor') && !backoff.factor && 'Factor is required'
    64                      };
    65                  }}>
    66                  {nestedFormApi => {
    67                      return (
    68                          <div className='row application-retry-options-list'>
    69                              {retryOptions.map((render, i) => (
    70                                  <div className='columns small-6 application-retry-options-list__item' key={i}>
    71                                      {render(nestedFormApi)}
    72                                  </div>
    73                              ))}
    74                          </div>
    75                      );
    76                  }}
    77              </Form>
    78          </NestedForm>
    79      );
    80  };
    81  
    82  export const ApplicationRetryOptions = ({
    83      formApi,
    84      initValues,
    85      field = 'retryStrategy',
    86      retry,
    87      setRetry,
    88      id
    89  }: {
    90      formApi: FormApi;
    91      field?: string;
    92      initValues?: models.RetryStrategy;
    93      retry?: boolean;
    94      setRetry?: (value: boolean) => any;
    95      id?: string;
    96  }) => {
    97      const [retryInternal, setRetryInternal] = React.useState(!!initValues);
    98  
    99      const toggleRetry = (value: boolean) => {
   100          if (!value) {
   101              const formState = formApi.getFormState();
   102              const values = formState.values;
   103              const errors = formState.errors;
   104  
   105              const newValues = omit(values, field);
   106              const newErrors = omit(errors, field);
   107  
   108              formApi.setFormState({
   109                  ...formState,
   110                  values: newValues,
   111                  errors: newErrors
   112              });
   113          }
   114          if (setRetry != null) {
   115              setRetry(value);
   116          } else {
   117              setRetryInternal(value);
   118          }
   119      };
   120      const isChecked = setRetry != null ? retry : retryInternal;
   121      return (
   122          <div className='application-retry-options'>
   123              <Checkbox id={`retry-${id}`} checked={isChecked} onChange={val => toggleRetry(val)} />
   124              <label htmlFor={`retry-${id}`}>Retry</label>
   125              {isChecked && <ApplicationRetryForm initValues={initValues} field={field} />}
   126          </div>
   127      );
   128  };