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

     1  import {DataLoader, DropDownMenu, Tooltip} from 'argo-ui';
     2  import * as React from 'react';
     3  import Moment from 'react-moment';
     4  import {Key, KeybindingContext, useNav} from 'argo-ui/v2';
     5  import {Cluster} from '../../../shared/components';
     6  import {Consumer, Context} from '../../../shared/context';
     7  import * as models from '../../../shared/models';
     8  import {ApplicationURLs} from '../application-urls';
     9  import * as AppUtils from '../utils';
    10  import {getAppDefaultSource, OperationState} from '../utils';
    11  import {ApplicationsLabels} from './applications-labels';
    12  import {ApplicationsSource} from './applications-source';
    13  import {services} from '../../../shared/services';
    14  import './applications-table.scss';
    15  
    16  export const ApplicationsTable = (props: {
    17      applications: models.Application[];
    18      syncApplication: (appName: string, appNamespace: string) => any;
    19      refreshApplication: (appName: string, appNamespace: string) => any;
    20      deleteApplication: (appName: string, appNamespace: string) => any;
    21  }) => {
    22      const [selectedApp, navApp, reset] = useNav(props.applications.length);
    23      const ctxh = React.useContext(Context);
    24  
    25      const {useKeybinding} = React.useContext(KeybindingContext);
    26  
    27      useKeybinding({keys: Key.DOWN, action: () => navApp(1)});
    28      useKeybinding({keys: Key.UP, action: () => navApp(-1)});
    29      useKeybinding({
    30          keys: Key.ESCAPE,
    31          action: () => {
    32              reset();
    33              return selectedApp > -1 ? true : false;
    34          }
    35      });
    36      useKeybinding({
    37          keys: Key.ENTER,
    38          action: () => {
    39              if (selectedApp > -1) {
    40                  ctxh.navigation.goto(`/applications/${props.applications[selectedApp].metadata.name}`);
    41                  return true;
    42              }
    43              return false;
    44          }
    45      });
    46  
    47      return (
    48          <Consumer>
    49              {ctx => (
    50                  <DataLoader load={() => services.viewPreferences.getPreferences()}>
    51                      {pref => {
    52                          const favList = pref.appList.favoritesAppList || [];
    53                          return (
    54                              <div className='applications-table argo-table-list argo-table-list--clickable'>
    55                                  {props.applications.map((app, i) => (
    56                                      <div
    57                                          key={AppUtils.appInstanceName(app)}
    58                                          className={`argo-table-list__row
    59                  applications-list__entry applications-list__entry--health-${app.status.health.status} ${selectedApp === i ? 'applications-tiles__selected' : ''}`}>
    60                                          <div
    61                                              className={`row applications-list__table-row`}
    62                                              onClick={e => ctx.navigation.goto(`/applications/${app.metadata.namespace}/${app.metadata.name}`, {}, {event: e})}>
    63                                              <div className='columns small-4'>
    64                                                  <div className='row'>
    65                                                      <div className=' columns small-2'>
    66                                                          <div>
    67                                                              <Tooltip content={favList?.includes(app.metadata.name) ? 'Remove Favorite' : 'Add Favorite'}>
    68                                                                  <button
    69                                                                      onClick={e => {
    70                                                                          e.stopPropagation();
    71                                                                          favList?.includes(app.metadata.name)
    72                                                                              ? favList.splice(favList.indexOf(app.metadata.name), 1)
    73                                                                              : favList.push(app.metadata.name);
    74                                                                          services.viewPreferences.updatePreferences({appList: {...pref.appList, favoritesAppList: favList}});
    75                                                                      }}>
    76                                                                      <i
    77                                                                          className={favList?.includes(app.metadata.name) ? 'fas fa-star' : 'far fa-star'}
    78                                                                          style={{
    79                                                                              cursor: 'pointer',
    80                                                                              marginRight: '7px',
    81                                                                              color: favList?.includes(app.metadata.name) ? '#FFCE25' : '#8fa4b1'
    82                                                                          }}
    83                                                                      />
    84                                                                  </button>
    85                                                              </Tooltip>
    86                                                              <ApplicationURLs urls={app.status.summary.externalURLs} />
    87                                                          </div>
    88                                                      </div>
    89                                                      <div className='show-for-xxlarge columns small-4'>Project:</div>
    90                                                      <div className='columns small-12 xxlarge-6'>{app.spec.project}</div>
    91                                                  </div>
    92                                                  <div className='row'>
    93                                                      <div className=' columns small-2' />
    94                                                      <div className='show-for-xxlarge columns small-4'>Name:</div>
    95                                                      <div className='columns small-12 xxlarge-6'>
    96                                                          <Tooltip
    97                                                              content={
    98                                                                  <>
    99                                                                      {app.metadata.name}
   100                                                                      <br />
   101                                                                      <Moment fromNow={true} ago={true}>
   102                                                                          {app.metadata.creationTimestamp}
   103                                                                      </Moment>
   104                                                                  </>
   105                                                              }>
   106                                                              <span>{app.metadata.name}</span>
   107                                                          </Tooltip>
   108                                                      </div>
   109                                                  </div>
   110                                              </div>
   111  
   112                                              <div className='columns small-6'>
   113                                                  <div className='row'>
   114                                                      <div className='show-for-xxlarge columns small-2'>Source:</div>
   115                                                      <div className='columns small-12 xxlarge-10 applications-table-source' style={{position: 'relative'}}>
   116                                                          <div className='applications-table-source__link'>
   117                                                              <ApplicationsSource source={getAppDefaultSource(app)} />
   118                                                          </div>
   119                                                          <div className='applications-table-source__labels'>
   120                                                              <ApplicationsLabels app={app} />
   121                                                          </div>
   122                                                      </div>
   123                                                  </div>
   124                                                  <div className='row'>
   125                                                      <div className='show-for-xxlarge columns small-2'>Destination:</div>
   126                                                      <div className='columns small-12 xxlarge-10'>
   127                                                          <Cluster server={app.spec.destination.server} name={app.spec.destination.name} />/{app.spec.destination.namespace}
   128                                                      </div>
   129                                                  </div>
   130                                              </div>
   131  
   132                                              <div className='columns small-2'>
   133                                                  <AppUtils.HealthStatusIcon state={app.status.health} /> <span>{app.status.health.status}</span> <br />
   134                                                  <AppUtils.ComparisonStatusIcon status={app.status.sync.status} />
   135                                                  <span>{app.status.sync.status}</span> <OperationState app={app} quiet={true} />
   136                                                  <DropDownMenu
   137                                                      anchor={() => (
   138                                                          <button className='argo-button argo-button--light argo-button--lg argo-button--short'>
   139                                                              <i className='fa fa-ellipsis-v' />
   140                                                          </button>
   141                                                      )}
   142                                                      items={[
   143                                                          {title: 'Sync', action: () => props.syncApplication(app.metadata.name, app.metadata.namespace)},
   144                                                          {title: 'Refresh', action: () => props.refreshApplication(app.metadata.name, app.metadata.namespace)},
   145                                                          {title: 'Delete', action: () => props.deleteApplication(app.metadata.name, app.metadata.namespace)}
   146                                                      ]}
   147                                                  />
   148                                              </div>
   149                                          </div>
   150                                      </div>
   151                                  ))}
   152                              </div>
   153                          );
   154                      }}
   155                  </DataLoader>
   156              )}
   157          </Consumer>
   158      );
   159  };