github.com/argoproj/argo-cd/v3@v3.2.1/ui/src/app/settings/components/clusters-list/clusters-list.tsx (about)

     1  import {DropDownMenu, ErrorNotification, NotificationType} from 'argo-ui';
     2  import {Tooltip, Toolbar} from 'argo-ui';
     3  import * as React from 'react';
     4  import {clusterName, ConnectionStateIcon, DataLoader, EmptyState, Page} from '../../../shared/components';
     5  import {Consumer, Context} from '../../../shared/context';
     6  import * as models from '../../../shared/models';
     7  import {services} from '../../../shared/services';
     8  import {AddAuthToToolbar} from '../../../shared/components';
     9  import {Observable} from 'rxjs';
    10  
    11  import './cluster-list.scss';
    12  
    13  // CustomTopBar component similar to FlexTopBar in application-list panel
    14  const CustomTopBar = (props: {toolbar?: Toolbar | Observable<Toolbar>}) => {
    15      const ctx = React.useContext(Context);
    16      const loadToolbar = AddAuthToToolbar(props.toolbar, ctx);
    17      return (
    18          <div className='top-bar row top-bar' key='tool-bar'>
    19              <DataLoader load={() => loadToolbar}>
    20                  {toolbar => (
    21                      <React.Fragment>
    22                          <div className='column small-11 flex-top-bar_center'>
    23                              <div className='top-bar'>
    24                                  <div className='text-center'>
    25                                      <span className='help-text'>
    26                                          Refer to CLI{' '}
    27                                          <a
    28                                              href='https://argo-cd.readthedocs.io/en/stable/operator-manual/cluster-management/#adding-a-cluster'
    29                                              target='_blank'
    30                                              rel='noopener noreferrer'>
    31                                              <i className='fa fa-external-link-alt' /> Documentation{' '}
    32                                          </a>{' '}
    33                                          for adding clusters.
    34                                      </span>
    35                                  </div>
    36                              </div>
    37                          </div>
    38                          <div className='columns small-1 top-bar__right-side'>{toolbar.tools}</div>
    39                      </React.Fragment>
    40                  )}
    41              </DataLoader>
    42          </div>
    43      );
    44  };
    45  
    46  export const ClustersList = () => {
    47      const clustersLoaderRef = React.useRef<DataLoader>();
    48      return (
    49          <Consumer>
    50              {ctx => (
    51                  <Page title='Clusters' toolbar={{breadcrumbs: [{title: 'Settings', path: '/settings'}, {title: 'Clusters'}]}} hideAuth={true}>
    52                      <CustomTopBar />
    53                      <div className='repos-list'>
    54                          <div className='argo-container'>
    55                              <DataLoader
    56                                  ref={clustersLoaderRef}
    57                                  load={() => services.clusters.list().then(clusters => clusters.sort((first, second) => first.name.localeCompare(second.name)))}>
    58                                  {(clusters: models.Cluster[]) =>
    59                                      (clusters.length > 0 && (
    60                                          <div className='argo-table-list argo-table-list--clickable'>
    61                                              <div className='argo-table-list__head'>
    62                                                  <div className='row'>
    63                                                      <div className='columns small-3'>NAME</div>
    64                                                      <div className='columns small-5'>URL</div>
    65                                                      <div className='columns small-2'>VERSION</div>
    66                                                      <div className='columns small-2'>CONNECTION STATUS</div>
    67                                                  </div>
    68                                              </div>
    69                                              {clusters.map(cluster => (
    70                                                  <div
    71                                                      className='argo-table-list__row'
    72                                                      key={cluster.server}
    73                                                      onClick={() => ctx.navigation.goto(`./${encodeURIComponent(cluster.server)}`)}>
    74                                                      <div className='row'>
    75                                                          <div className='columns small-3'>
    76                                                              <i className='icon argo-icon-hosts' />
    77                                                              <Tooltip content={clusterName(cluster.name)}>
    78                                                                  <span>{clusterName(cluster.name)}</span>
    79                                                              </Tooltip>
    80                                                          </div>
    81                                                          <div className='columns small-5'>
    82                                                              <Tooltip content={cluster.server}>
    83                                                                  <span>{cluster.server}</span>
    84                                                              </Tooltip>
    85                                                          </div>
    86                                                          <div className='columns small-2'>{cluster.info.serverVersion}</div>
    87                                                          <div className='columns small-2'>
    88                                                              <ConnectionStateIcon state={cluster.info.connectionState} /> {cluster.info.connectionState.status}
    89                                                              <DropDownMenu
    90                                                                  anchor={() => (
    91                                                                      <button className='argo-button argo-button--light argo-button--lg argo-button--short'>
    92                                                                          <i className='fa fa-ellipsis-v' />
    93                                                                      </button>
    94                                                                  )}
    95                                                                  items={[
    96                                                                      {
    97                                                                          title: 'Delete',
    98                                                                          action: async () => {
    99                                                                              const confirmed = await ctx.popup.confirm(
   100                                                                                  'Delete cluster?',
   101                                                                                  `Are you sure you want to delete cluster: ${cluster.name}`
   102                                                                              );
   103                                                                              if (confirmed) {
   104                                                                                  try {
   105                                                                                      await services.clusters.delete(cluster.server).finally(() => {
   106                                                                                          ctx.navigation.goto('.', {new: null}, {replace: true});
   107                                                                                          if (clustersLoaderRef.current) {
   108                                                                                              clustersLoaderRef.current.reload();
   109                                                                                          }
   110                                                                                      });
   111                                                                                  } catch (e) {
   112                                                                                      ctx.notifications.show({
   113                                                                                          content: <ErrorNotification title='Unable to delete cluster' e={e} />,
   114                                                                                          type: NotificationType.Error
   115                                                                                      });
   116                                                                                  }
   117                                                                              }
   118                                                                          }
   119                                                                      }
   120                                                                  ]}
   121                                                              />
   122                                                          </div>
   123                                                      </div>
   124                                                  </div>
   125                                              ))}
   126                                          </div>
   127                                      )) || (
   128                                          <EmptyState icon='argo-icon-hosts'>
   129                                              <h4>No clusters connected</h4>
   130                                              <h5>Connect more clusters using argocd CLI</h5>
   131                                          </EmptyState>
   132                                      )
   133                                  }
   134                              </DataLoader>
   135                          </div>
   136                      </div>
   137                  </Page>
   138              )}
   139          </Consumer>
   140      );
   141  };