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

     1  import {DropDown} from 'argo-ui';
     2  import * as React from 'react';
     3  import * as classNames from 'classnames';
     4  import * as models from '../../../shared/models';
     5  import {ResourceIcon} from '../resource-icon';
     6  import {ResourceLabel} from '../resource-label';
     7  import {ComparisonStatusIcon, HealthStatusIcon, nodeKey, createdOrNodeKey} from '../utils';
     8  import {Consumer} from '../../../shared/context';
     9  import * as _ from 'lodash';
    10  import Moment from 'react-moment';
    11  import {format} from 'date-fns';
    12  import {ResourceNode, ResourceRef} from '../../../shared/models';
    13  
    14  export const ApplicationResourceList = ({
    15      resources,
    16      onNodeClick,
    17      nodeMenu,
    18      tree
    19  }: {
    20      resources: models.ResourceStatus[];
    21      onNodeClick?: (fullName: string) => any;
    22      nodeMenu?: (node: models.ResourceNode) => React.ReactNode;
    23      tree?: models.ApplicationTree;
    24  }) => {
    25      function getResNode(nodes: ResourceNode[], nodeId: string): models.ResourceNode {
    26          for (const node of nodes) {
    27              if (nodeKey(node) === nodeId) {
    28                  return node;
    29              }
    30          }
    31          return null;
    32      }
    33      const parentNode = ((resources || []).length > 0 && (getResNode(tree.nodes, nodeKey(resources[0])) as ResourceNode)?.parentRefs?.[0]) || ({} as ResourceRef);
    34      const searchParams = new URLSearchParams(window.location.search);
    35      const view = searchParams.get('view');
    36  
    37      const ParentRefDetails = () => {
    38          return Object.keys(parentNode).length > 0 ? (
    39              <div className='resource-parent-node-info-title'>
    40                  <div>Parent Node Info</div>
    41                  <div className='resource-parent-node-info-title__label'>
    42                      <div>Name:</div>
    43                      <div>{parentNode?.name}</div>
    44                  </div>
    45                  <div className='resource-parent-node-info-title__label'>
    46                      <div>Kind:</div>
    47                      <div>{parentNode?.kind}</div>
    48                  </div>
    49              </div>
    50          ) : (
    51              <div />
    52          );
    53      };
    54      return (
    55          <div>
    56              {/* Display only when the view is set to  or network */}
    57              {(view === 'tree' || view === 'network') && (
    58                  <div className='resource-details__header' style={{paddingTop: '20px'}}>
    59                      <ParentRefDetails />
    60                  </div>
    61              )}
    62              <div className='argo-table-list argo-table-list--clickable'>
    63                  <div className='argo-table-list__head'>
    64                      <div className='row'>
    65                          <div className='columns small-1 xxxlarge-1' />
    66                          <div className='columns small-2 xxxlarge-1'>NAME</div>
    67                          <div className='columns small-1 xxxlarge-1'>GROUP/KIND</div>
    68                          <div className='columns small-1 xxxlarge-1'>SYNC ORDER</div>
    69                          <div className='columns small-2 xxxlarge-1'>NAMESPACE</div>
    70                          {(parentNode.kind === 'Rollout' || parentNode.kind === 'Deployment') && <div className='columns small-1 xxxlarge-1'>REVISION</div>}
    71                          <div className='columns small-2 xxxlarge-1'>CREATED AT</div>
    72                          <div className='columns small-2 xxxlarge-1'>STATUS</div>
    73                      </div>
    74                  </div>
    75                  {resources
    76                      .sort((first, second) => -createdOrNodeKey(first).localeCompare(createdOrNodeKey(second)))
    77                      .map(res => (
    78                          <div
    79                              key={nodeKey(res)}
    80                              className={classNames('argo-table-list__row', {
    81                                  'application-resource-tree__node--orphaned': res.orphaned
    82                              })}
    83                              onClick={() => onNodeClick(nodeKey(res))}>
    84                              <div className='row'>
    85                                  <div className='columns small-1 xxxlarge-1'>
    86                                      <div className='application-details__resource-icon'>
    87                                          <ResourceIcon kind={res.kind} />
    88                                          <br />
    89                                          <div>{ResourceLabel({kind: res.kind})}</div>
    90                                      </div>
    91                                  </div>
    92                                  <div className='columns small-2 xxxlarge-1'>
    93                                      {res.name}
    94                                      {res.kind === 'Application' && (
    95                                          <Consumer>
    96                                              {ctx => (
    97                                                  <span className='application-details__external_link'>
    98                                                      <a
    99                                                          href={ctx.baseHref + 'applications/' + res.namespace + '/' + res.name}
   100                                                          onClick={e => e.stopPropagation()}
   101                                                          title='Open application'>
   102                                                          <i className='fa fa-external-link-alt' />
   103                                                      </a>
   104                                                  </span>
   105                                              )}
   106                                          </Consumer>
   107                                      )}
   108                                  </div>
   109                                  <div className='columns small-1 xxxlarge-1'>{[res.group, res.kind].filter(item => !!item).join('/')}</div>
   110                                  <div className='columns small-1 xxxlarge-1'>{res.syncWave || '-'}</div>
   111                                  <div className='columns small-2 xxxlarge-1'>{res.namespace}</div>
   112                                  {res.kind === 'ReplicaSet' &&
   113                                      ((getResNode(tree.nodes, nodeKey(res)) as ResourceNode).info || [])
   114                                          .filter(tag => !tag.name.includes('Node'))
   115                                          .slice(0, 4)
   116                                          .map((tag, i) => {
   117                                              return (
   118                                                  <div key={i} className='columns small-1 xxxlarge-1'>
   119                                                      {tag?.value?.split(':')[1] || '-'}
   120                                                  </div>
   121                                              );
   122                                          })}
   123  
   124                                  <div className='columns small-2 xxxlarge-1'>
   125                                      {res.createdAt && (
   126                                          <span>
   127                                              <Moment fromNow={true} ago={true}>
   128                                                  {res.createdAt}
   129                                              </Moment>
   130                                              &nbsp;ago &nbsp; {format(new Date(res.createdAt), 'MM/dd/yy')}
   131                                          </span>
   132                                      )}
   133                                  </div>
   134                                  <div className='columns small-2 xxxlarge-1'>
   135                                      {res.health && (
   136                                          <React.Fragment>
   137                                              <HealthStatusIcon state={res.health} /> {res.health.status} &nbsp;
   138                                          </React.Fragment>
   139                                      )}
   140                                      {res.status && <ComparisonStatusIcon status={res.status} resource={res} label={true} />}
   141                                      {res.hook && <i title='Resource lifecycle hook' className='fa fa-anchor' />}
   142                                      <div className='application-details__node-menu'>
   143                                          <DropDown
   144                                              isMenu={true}
   145                                              anchor={() => (
   146                                                  <button className='argo-button argo-button--light argo-button--lg argo-button--short'>
   147                                                      <i className='fa fa-ellipsis-v' />
   148                                                  </button>
   149                                              )}>
   150                                              {nodeMenu({
   151                                                  name: res.name,
   152                                                  version: res.version,
   153                                                  kind: res.kind,
   154                                                  namespace: res.namespace,
   155                                                  group: res.group,
   156                                                  info: null,
   157                                                  uid: '',
   158                                                  resourceVersion: null,
   159                                                  parentRefs: []
   160                                              })}
   161                                          </DropDown>
   162                                      </div>
   163                                  </div>
   164                              </div>
   165                          </div>
   166                      ))}
   167              </div>
   168          </div>
   169      );
   170  };