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

     1  import {DataLoader, Tab, Tabs} from 'argo-ui';
     2  import * as moment from 'moment';
     3  import * as React from 'react';
     4  
     5  import {YamlEditor} from '../../../shared/components';
     6  import * as models from '../../../shared/models';
     7  import {services} from '../../../shared/services';
     8  import {ApplicationResourcesDiff} from '../application-resources-diff/application-resources-diff';
     9  import {ComparisonStatusIcon, getPodStateReason, HealthStatusIcon} from '../utils';
    10  
    11  require('./application-node-info.scss');
    12  
    13  export const ApplicationNodeInfo = (props: {
    14      application: models.Application;
    15      node: models.ResourceNode;
    16      live: models.State;
    17      controlled: {summary: models.ResourceStatus; state: models.ResourceDiff};
    18  }) => {
    19      const attributes: {title: string; value: any}[] = [
    20          {title: 'KIND', value: props.node.kind},
    21          {title: 'NAME', value: props.node.name},
    22          {title: 'NAMESPACE', value: props.node.namespace}
    23      ];
    24      if (props.node.createdAt) {
    25          attributes.push({
    26              title: 'CREATED_AT',
    27              value: moment
    28                  .utc(props.node.createdAt)
    29                  .local()
    30                  .format('MM/DD/YYYY HH:mm:ss')
    31          });
    32      }
    33      if ((props.node.images || []).length) {
    34          attributes.push({
    35              title: 'IMAGES',
    36              value: (
    37                  <div className='application-node-info__labels'>
    38                      {(props.node.images || []).sort().map(image => (
    39                          <span className='application-node-info__label' key={image}>
    40                              {image}
    41                          </span>
    42                      ))}
    43                  </div>
    44              )
    45          });
    46      }
    47      if (props.live) {
    48          if (props.node.kind === 'Pod') {
    49              const {reason, message} = getPodStateReason(props.live);
    50              attributes.push({title: 'STATE', value: reason});
    51              if (message) {
    52                  attributes.push({title: 'STATE DETAILS', value: message});
    53              }
    54          } else if (props.node.kind === 'Service') {
    55              attributes.push({title: 'TYPE', value: props.live.spec.type});
    56              let hostNames = '';
    57              const status = props.live.status;
    58              if (status && status.loadBalancer && status.loadBalancer.ingress) {
    59                  hostNames = (status.loadBalancer.ingress || []).map((item: any) => item.hostname || item.ip).join(', ');
    60              }
    61              attributes.push({title: 'HOSTNAMES', value: hostNames});
    62          }
    63      }
    64  
    65      if (props.controlled) {
    66          if (!props.controlled.summary.hook) {
    67              attributes.push({
    68                  title: 'STATUS',
    69                  value: (
    70                      <span>
    71                          <ComparisonStatusIcon status={props.controlled.summary.status} resource={props.controlled.summary} label={true} />
    72                      </span>
    73                  )
    74              } as any);
    75          }
    76          if (props.controlled.summary.health !== undefined) {
    77              attributes.push({
    78                  title: 'HEALTH',
    79                  value: (
    80                      <span>
    81                          <HealthStatusIcon state={props.controlled.summary.health} /> {props.controlled.summary.health.status}
    82                      </span>
    83                  )
    84              } as any);
    85              if (props.controlled.summary.health.message) {
    86                  attributes.push({title: 'HEALTH DETAILS', value: props.controlled.summary.health.message});
    87              }
    88          }
    89      }
    90  
    91      const tabs: Tab[] = [
    92          {
    93              key: 'manifest',
    94              title: 'Live Manifest',
    95              content: (
    96                  <YamlEditor
    97                      input={props.live}
    98                      hideModeButtons={!props.live}
    99                      onSave={(patch, patchType) => services.applications.patchResource(props.application.metadata.name, props.node, patch, patchType)}
   100                  />
   101              )
   102          }
   103      ];
   104      if (props.controlled && !props.controlled.summary.hook) {
   105          tabs.push({
   106              key: 'diff',
   107              icon: 'fa fa-file-medical',
   108              title: 'Diff',
   109              content: <ApplicationResourcesDiff states={[props.controlled.state]} />
   110          });
   111          tabs.push({
   112              key: 'desiredManifest',
   113              title: 'Desired Manifest',
   114              content: <YamlEditor input={props.controlled.state.targetState} hideModeButtons={true} />
   115          });
   116      }
   117  
   118      return (
   119          <div>
   120              <div className='white-box'>
   121                  <div className='white-box__details'>
   122                      {attributes.map(attr => (
   123                          <div className='row white-box__details-row' key={attr.title}>
   124                              <div className='columns small-3'>{attr.title}</div>
   125                              <div className='columns small-9'>{attr.value}</div>
   126                          </div>
   127                      ))}
   128                  </div>
   129              </div>
   130  
   131              <div className='application-node-info__manifest'>
   132                  <DataLoader load={() => services.viewPreferences.getPreferences()}>
   133                      {pref => (
   134                          <Tabs
   135                              selectedTabKey={(tabs.length > 1 && pref.appDetails.resourceView) || 'manifest'}
   136                              tabs={tabs}
   137                              onTabSelected={selected => {
   138                                  services.viewPreferences.updatePreferences({appDetails: {...pref.appDetails, resourceView: selected as any}});
   139                              }}
   140                          />
   141                      )}
   142                  </DataLoader>
   143              </div>
   144          </div>
   145      );
   146  };