github.com/argoproj/argo-cd@v1.8.7/ui/src/app/applications/components/applications-sync-panel/applications-sync-panel.tsx (about)

     1  import {ErrorNotification, NotificationType, SlidingPanel} from 'argo-ui';
     2  import * as React from 'react';
     3  import {Checkbox, 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 {ComparisonStatusIcon, HealthStatusIcon, OperationPhaseIcon} from '../utils';
     9  
    10  interface Progress {
    11      percentage: number;
    12      title: string;
    13  }
    14  
    15  export const ApplicationsSyncPanel = ({show, apps, hide}: {show: boolean; apps: models.Application[]; hide: () => void}) => {
    16      const [form, setForm] = React.useState<FormApi>(null);
    17      const [progress, setProgress] = React.useState<Progress>(null);
    18      const getSelectedApps = (params: any) => apps.filter((_, i) => params['app/' + i]);
    19      return (
    20          <Consumer>
    21              {ctx => (
    22                  <SlidingPanel
    23                      isMiddle={true}
    24                      isShown={show}
    25                      onClose={() => hide()}
    26                      header={
    27                          <div>
    28                              <button className='argo-button argo-button--base' onClick={() => form.submitForm(null)}>
    29                                  Sync
    30                              </button>{' '}
    31                              <button onClick={() => hide()} className='argo-button argo-button--base-o'>
    32                                  Cancel
    33                              </button>
    34                          </div>
    35                      }>
    36                      <Form
    37                          onSubmit={async (params: any) => {
    38                              const selectedApps = getSelectedApps(params);
    39                              if (selectedApps.length === 0) {
    40                                  ctx.notifications.show({content: `No apps selected`, type: NotificationType.Error});
    41                                  return;
    42                              }
    43                              const syncStrategy: models.SyncStrategy = params.applyOnly ? {apply: {force: params.force}} : {hook: {force: params.force}};
    44                              setProgress({percentage: 0, title: 'Starting...'});
    45                              let i = 0;
    46                              for (const app of selectedApps) {
    47                                  await services.applications.sync(app.metadata.name, app.spec.source.targetRevision, params.prune, params.dryRun, syncStrategy, null).catch(e => {
    48                                      ctx.notifications.show({
    49                                          content: <ErrorNotification title={`Unable to sync ${app.metadata.name}`} e={e} />,
    50                                          type: NotificationType.Error
    51                                      });
    52                                  });
    53                                  i++;
    54                                  setProgress({
    55                                      percentage: i / selectedApps.length,
    56                                      title: `${i} of ${selectedApps.length} apps now syncing`
    57                                  });
    58                              }
    59                              setProgress({percentage: 100, title: 'Complete'});
    60                          }}
    61                          getApi={setForm}>
    62                          {formApi => (
    63                              <React.Fragment>
    64                                  <div className='argo-form-row'>
    65                                      <h4>Sync app(s)</h4>
    66                                      {progress !== null && <ProgressPopup onClose={() => setProgress(null)} percentage={progress.percentage} title={progress.title} />}
    67                                      <label>Options:</label>
    68                                      <div style={{paddingLeft: '1em'}}>
    69                                          <label>
    70                                              <Checkbox field='prune' /> Prune
    71                                          </label>
    72                                          &nbsp;
    73                                          <label>
    74                                              <Checkbox field='dryRun' /> Dry Run
    75                                          </label>
    76                                          &nbsp;
    77                                          <label>
    78                                              <Checkbox field='applyOnly' /> Apply Only
    79                                          </label>
    80                                          &nbsp;
    81                                          <label>
    82                                              <Checkbox field='force' /> Force
    83                                          </label>
    84                                      </div>
    85                                      <label>
    86                                          Apps (<a onClick={() => apps.forEach((_, i) => formApi.setValue('app/' + i, true))}>all</a>/
    87                                          <a onClick={() => apps.forEach((app, i) => formApi.setValue('app/' + i, app.status.sync.status === models.SyncStatuses.OutOfSync))}>
    88                                              out of sync
    89                                          </a>
    90                                          /<a onClick={() => apps.forEach((_, i) => formApi.setValue('app/' + i, false))}>none</a>
    91                                          ):
    92                                      </label>
    93                                      <div style={{paddingLeft: '1em'}}>
    94                                          {apps.map((app, i) => (
    95                                              <label key={app.metadata.name}>
    96                                                  <Checkbox field={`app/${i}`} />
    97                                                  &nbsp;
    98                                                  {app.metadata.name}
    99                                                  &nbsp;
   100                                                  <ComparisonStatusIcon status={app.status.sync.status} />
   101                                                  &nbsp;
   102                                                  <HealthStatusIcon state={app.status.health} />
   103                                                  &nbsp;
   104                                                  <OperationPhaseIcon app={app} />
   105                                                  <br />
   106                                              </label>
   107                                          ))}
   108                                      </div>
   109                                  </div>
   110                              </React.Fragment>
   111                          )}
   112                      </Form>
   113                  </SlidingPanel>
   114              )}
   115          </Consumer>
   116      );
   117  };