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

     1  import {HelpIcon} from 'argo-ui';
     2  import * as React from 'react';
     3  import {DataLoader} from '../../../shared/components';
     4  import {Revision} from '../../../shared/components/revision';
     5  import {Timestamp} from '../../../shared/components/timestamp';
     6  import * as models from '../../../shared/models';
     7  import {services} from '../../../shared/services';
     8  import * as utils from '../utils';
     9  import {ApplicationSyncWindowStatusIcon, ComparisonStatusIcon, getAppOperationState, HealthStatusIcon, OperationState, syncStatusMessage} from '../utils';
    10  import {RevisionMetadataPanel} from './revision-metadata-panel';
    11  
    12  require('./application-status-panel.scss');
    13  
    14  interface Props {
    15      application: models.Application;
    16      showOperation?: () => any;
    17      showConditions?: () => any;
    18  }
    19  
    20  export const ApplicationStatusPanel = ({application, showOperation, showConditions}: Props) => {
    21      const today = new Date();
    22  
    23      let daysSinceLastSynchronized = 0;
    24      const history = application.status.history || [];
    25      if (history.length > 0) {
    26          const deployDate = new Date(history[history.length - 1].deployedAt);
    27          daysSinceLastSynchronized = Math.round(Math.abs((today.getTime() - deployDate.getTime()) / (24 * 60 * 60 * 1000)));
    28      }
    29      const cntByCategory = (application.status.conditions || []).reduce(
    30          (map, next) => map.set(utils.getConditionCategory(next), (map.get(utils.getConditionCategory(next)) || 0) + 1),
    31          new Map<string, number>()
    32      );
    33      const appOperationState = getAppOperationState(application);
    34      if (application.metadata.deletionTimestamp) {
    35          showOperation = null;
    36      }
    37  
    38      return (
    39          <div className='application-status-panel row'>
    40              <div className='application-status-panel__item columns small-2'>
    41                  <div className='application-status-panel__item-value'>
    42                      <HealthStatusIcon state={application.status.health} />
    43                      &nbsp;
    44                      {application.status.health.status}
    45                      <HelpIcon title='The health status of your app' />
    46                  </div>
    47                  <div className='application-status-panel__item-name'>{application.status.health.message}</div>
    48              </div>
    49              <div className='application-status-panel__item columns small-2' style={{position: 'relative'}}>
    50                  <div className='application-status-panel__item-value'>
    51                      <ComparisonStatusIcon status={application.status.sync.status} label={true} />
    52                      <HelpIcon title='Whether or not the version of your app is up to date with your repo. You may wish to sync your app if it is out-of-sync.' />
    53                  </div>
    54                  <div className='application-status-panel__item-name'>{syncStatusMessage(application)}</div>
    55                  <div className='application-status-panel__item-name'>
    56                      {application.status && application.status.sync && application.status.sync.revision && (
    57                          <RevisionMetadataPanel appName={application.metadata.name} type={application.spec.source.chart && 'helm'} revision={application.status.sync.revision} />
    58                      )}
    59                  </div>
    60              </div>
    61              {appOperationState && (
    62                  <div className='application-status-panel__item columns small-4 '>
    63                      <div className={`application-status-panel__item-value application-status-panel__item-value--${appOperationState.phase}`}>
    64                          <a onClick={() => showOperation && showOperation()}>
    65                              <OperationState app={application} />
    66                              <HelpIcon
    67                                  title={
    68                                      'Whether or not your last app sync was successful. It has been ' +
    69                                      daysSinceLastSynchronized +
    70                                      ' days since last sync. Click for the status of that sync.'
    71                                  }
    72                              />
    73                          </a>
    74                      </div>
    75                      {appOperationState.syncResult && appOperationState.syncResult.revision && (
    76                          <div className='application-status-panel__item-name'>
    77                              To <Revision repoUrl={application.spec.source.repoURL} revision={appOperationState.syncResult.revision} />
    78                          </div>
    79                      )}
    80                      <div className='application-status-panel__item-name'>
    81                          {appOperationState.phase} <Timestamp date={appOperationState.finishedAt || appOperationState.startedAt} />
    82                      </div>
    83                      {(appOperationState.syncResult && appOperationState.syncResult.revision && (
    84                          <RevisionMetadataPanel
    85                              appName={application.metadata.name}
    86                              type={application.spec.source.chart && 'helm'}
    87                              revision={appOperationState.syncResult.revision}
    88                          />
    89                      )) || <div className='application-status-panel__item-name'>{appOperationState.message}</div>}
    90                  </div>
    91              )}
    92              {application.status.conditions && (
    93                  <div className={`application-status-panel__item columns small-2`}>
    94                      <div className='application-status-panel__item-value' onClick={() => showConditions && showConditions()}>
    95                          {cntByCategory.get('info') && <a className='info'>{cntByCategory.get('info')} Info</a>}
    96                          {cntByCategory.get('warning') && <a className='warning'>{cntByCategory.get('warning')} Warnings</a>}
    97                          {cntByCategory.get('error') && <a className='error'>{cntByCategory.get('error')} Errors</a>}
    98                      </div>
    99                  </div>
   100              )}
   101              <DataLoader
   102                  noLoaderOnInputChange={true}
   103                  input={application.metadata.name}
   104                  load={async name => {
   105                      return await services.applications.getApplicationSyncWindowState(name);
   106                  }}>
   107                  {(data: models.ApplicationSyncWindowState) => (
   108                      <React.Fragment>
   109                          <div className='application-status-panel__item columns small-2' style={{position: 'relative'}}>
   110                              <div className='application-status-panel__item-value'>
   111                                  {data.assignedWindows && (
   112                                      <React.Fragment>
   113                                          <ApplicationSyncWindowStatusIcon project={application.spec.project} state={data} />
   114                                          <HelpIcon
   115                                              title={
   116                                                  'The aggregate state of sync windows for this app. ' +
   117                                                  'Red: no syncs allowed. ' +
   118                                                  'Yellow: manual syncs allowed. ' +
   119                                                  'Green: all syncs allowed'
   120                                              }
   121                                          />
   122                                      </React.Fragment>
   123                                  )}
   124                              </div>
   125                          </div>
   126                      </React.Fragment>
   127                  )}
   128              </DataLoader>
   129          </div>
   130      );
   131  };