github.com/argoproj/argo-cd/v3@v3.2.1/ui/src/app/applications/components/applications-refresh-panel/applications-refresh-panel.tsx (about)

     1  import {ErrorNotification, NotificationType, SlidingPanel} from 'argo-ui';
     2  import * as React from 'react';
     3  import {Form, FormApi} from 'react-form';
     4  import {ProgressPopup} from '../../../shared/components';
     5  import {Consumer} from '../../../shared/context';
     6  import * as models from '../../../shared/models';
     7  import {services} from '../../../shared/services';
     8  import {ApplicationSelector} from '../../../shared/components';
     9  
    10  interface Progress {
    11      percentage: number;
    12      title: string;
    13  }
    14  
    15  const RefreshTypes = ['normal', 'hard'];
    16  
    17  export const ApplicationsRefreshPanel = ({show, apps, hide}: {show: boolean; apps: models.Application[]; hide: () => void}) => {
    18      const [form, setForm] = React.useState<FormApi>(null);
    19      const [progress, setProgress] = React.useState<Progress>(null);
    20      const getSelectedApps = (params: any) => apps.filter((_, i) => params['app/' + i]);
    21  
    22      return (
    23          <Consumer>
    24              {ctx => (
    25                  <SlidingPanel
    26                      isMiddle={true}
    27                      isShown={show}
    28                      onClose={() => hide()}
    29                      header={
    30                          <div>
    31                              <button className='argo-button argo-button--base' onClick={() => form.submitForm(null)}>
    32                                  Refresh
    33                              </button>{' '}
    34                              <button onClick={() => hide()} className='argo-button argo-button--base-o'>
    35                                  Cancel
    36                              </button>
    37                          </div>
    38                      }>
    39                      <Form
    40                          defaultValues={{refreshType: 'normal'}}
    41                          onSubmit={async (params: any) => {
    42                              const selectedApps = getSelectedApps(params);
    43                              if (selectedApps.length === 0) {
    44                                  ctx.notifications.show({content: `No apps selected`, type: NotificationType.Error});
    45                                  return;
    46                              }
    47  
    48                              setProgress({percentage: 0, title: 'Refreshing applications'});
    49                              let i = 0;
    50                              const refreshActions = [];
    51                              for (const app of selectedApps) {
    52                                  const refreshAction = async () => {
    53                                      await services.applications.get(app.metadata.name, app.metadata.namespace, params.refreshType).catch(e => {
    54                                          ctx.notifications.show({
    55                                              content: <ErrorNotification title={`Unable to refresh ${app.metadata.name}`} e={e} />,
    56                                              type: NotificationType.Error
    57                                          });
    58                                      });
    59                                      i++;
    60                                      setProgress({
    61                                          percentage: i / selectedApps.length,
    62                                          title: `Refreshed ${i} of ${selectedApps.length} applications`
    63                                      });
    64                                  };
    65                                  refreshActions.push(refreshAction());
    66  
    67                                  if (refreshActions.length >= 20) {
    68                                      await Promise.all(refreshActions);
    69                                      refreshActions.length = 0;
    70                                  }
    71                              }
    72                              await Promise.all(refreshActions);
    73                              setProgress({percentage: 100, title: 'Complete'});
    74                          }}
    75                          getApi={setForm}>
    76                          {formApi => (
    77                              <div className='argo-form-row' style={{marginTop: 0}}>
    78                                  <h4>Refresh app(s)</h4>
    79                                  {progress !== null && <ProgressPopup onClose={() => setProgress(null)} percentage={progress.percentage} title={progress.title} />}
    80                                  <div style={{marginBottom: '1em'}}>
    81                                      <label>Refresh Type</label>
    82                                      <div className='row application-sync-options'>
    83                                          {RefreshTypes.map(refreshType => (
    84                                              <label key={refreshType} style={{paddingRight: '1.5em', marginTop: '0.4em'}}>
    85                                                  <input
    86                                                      type='radio'
    87                                                      value={refreshType}
    88                                                      checked={formApi.values.refreshType === refreshType}
    89                                                      onChange={() => formApi.setValue('refreshType', refreshType)}
    90                                                      style={{marginRight: '5px', transform: 'translateY(2px)'}}
    91                                                  />
    92                                                  {refreshType}
    93                                              </label>
    94                                          ))}
    95                                      </div>
    96                                  </div>
    97                                  {show && <ApplicationSelector apps={apps} formApi={formApi} />}
    98                              </div>
    99                          )}
   100                      </Form>
   101                  </SlidingPanel>
   102              )}
   103          </Consumer>
   104      );
   105  };