github.com/argoproj/argo-cd@v1.8.7/ui/src/app/settings/components/account-details/account-details.tsx (about)

     1  import {ErrorNotification, FormField, NotificationType} from 'argo-ui';
     2  import * as React from 'react';
     3  import {Form, Text} from 'react-form';
     4  import {RouteComponentProps} from 'react-router';
     5  
     6  import {DataLoader, Page, Timestamp} from '../../../shared/components';
     7  import {Context} from '../../../shared/context';
     8  import {Account, Token} from '../../../shared/models';
     9  import {services} from '../../../shared/services';
    10  
    11  import {convertExpiresInToSeconds, validExpiresIn} from '../utils';
    12  
    13  require('./account-details.scss');
    14  
    15  export const AccountDetails = (props: RouteComponentProps<{name: string}>) => {
    16      const ctx = React.useContext(Context);
    17      const [newToken, setNewToken] = React.useState(null);
    18      const tokensLoaderRef = React.useRef<DataLoader>();
    19      return (
    20          <Page
    21              title={props.match.params.name}
    22              toolbar={{
    23                  breadcrumbs: [{title: 'Settings', path: '/settings'}, {title: 'Accounts', path: '/settings/accounts'}, {title: props.match.params.name}]
    24              }}>
    25              <p />
    26              <div className='argo-container account-details'>
    27                  <DataLoader input={props.match.params.name} load={(name: string) => services.accounts.get(name)}>
    28                      {(account: Account) => (
    29                          <React.Fragment>
    30                              <div className='white-box'>
    31                                  <div className='white-box__details'>
    32                                      <div className='row white-box__details-row'>
    33                                          <div className='columns small-3'>NAME:</div>
    34                                          <div className='columns small-9'>{account.name}</div>
    35                                      </div>
    36                                      <div className='row white-box__details-row'>
    37                                          <div className='columns small-3'>ENABLED:</div>
    38                                          <div className='columns small-9'>{(account.enabled && 'true') || 'false'}</div>
    39                                      </div>
    40                                      <div className='row white-box__details-row'>
    41                                          <div className='columns small-3'>CAPABILITIES:</div>
    42                                          <div className='columns small-9'>{account.capabilities.join(', ')}</div>
    43                                      </div>
    44                                  </div>
    45                              </div>
    46  
    47                              <h4>Tokens</h4>
    48                              <Form
    49                                  onSubmit={async (params, event, api) => {
    50                                      const expiresIn = convertExpiresInToSeconds(params.expiresIn);
    51                                      const confirmed = await ctx.popup.confirm('Generate new token?', 'Are you sure you want to generate new token?');
    52                                      if (!confirmed) {
    53                                          return;
    54                                      }
    55                                      try {
    56                                          setNewToken(await services.accounts.createToken(props.match.params.name, params.id, expiresIn));
    57                                          api.resetAll();
    58                                          if (tokensLoaderRef.current) {
    59                                              tokensLoaderRef.current.reload();
    60                                          }
    61                                      } catch (e) {
    62                                          ctx.notifications.show({
    63                                              content: <ErrorNotification title='Unable to generate new token' e={e} />,
    64                                              type: NotificationType.Error
    65                                          });
    66                                      }
    67                                  }}
    68                                  validateError={params => ({
    69                                      expiresIn: !validExpiresIn(params.expiresIn) && 'Must be in the "[0-9]+[smhd]" format'
    70                                  })}>
    71                                  {api => (
    72                                      <form onSubmit={api.submitForm}>
    73                                          <div className='row argo-table-list__row'>
    74                                              <div className='columns small-10'>
    75                                                  <div className='argo-form-row'>
    76                                                      <FormField formApi={api} label='Token ID' field='id' component={Text} />
    77                                                  </div>
    78                                                  <div className='argo-form-row'>
    79                                                      <FormField formApi={api} label='Expires In' field='expiresIn' component={Text} />
    80                                                  </div>
    81                                              </div>
    82                                              <div className='columns small-2'>
    83                                                  <div className='argo-form-row'>
    84                                                      <a onClick={() => api.submitForm(null)}>Generate New</a>
    85                                                  </div>
    86                                              </div>
    87                                          </div>
    88                                      </form>
    89                                  )}
    90                              </Form>
    91                              {newToken && (
    92                                  <div className='white-box account-details__new-token'>
    93                                      <h5>New Token:</h5>
    94                                      <p>{newToken}</p>
    95                                      <i className='fa fa-times account-details__remove-token' title='Remove' onClick={() => setNewToken(null)} />
    96                                  </div>
    97                              )}
    98                              <DataLoader ref={tokensLoaderRef} input={props.match.params.name} load={(name: string) => services.accounts.get(name).then(acc => acc.tokens || [])}>
    99                                  {(tokens: Token[]) =>
   100                                      (tokens.length > 0 && (
   101                                          <div className='argo-table-list'>
   102                                              <div className='argo-table-list__head'>
   103                                                  <div className='row'>
   104                                                      <div className='columns small-4'>ID</div>
   105                                                      <div className='columns small-4'>ISSUED AT</div>
   106                                                      <div className='columns small-4'>EXPIRES AT</div>
   107                                                  </div>
   108                                              </div>
   109                                              {tokens.map(token => (
   110                                                  <div className='argo-table-list__row' key={token.id}>
   111                                                      <div className='row'>
   112                                                          <div className='columns small-4'>{token.id}</div>
   113                                                          <div className='columns small-4'>
   114                                                              <Timestamp date={token.issuedAt * 1000} />
   115                                                          </div>
   116                                                          <div className='columns small-4'>
   117                                                              {(token.expiresAt && <Timestamp date={token.expiresAt * 1000} />) || <span>Never</span>}
   118                                                              <i
   119                                                                  className='fa fa-times account-details__remove-token'
   120                                                                  title='Delete'
   121                                                                  onClick={async () => {
   122                                                                      const confirmed = await ctx.popup.confirm(
   123                                                                          'Delete Token?',
   124                                                                          `Are you sure you want to delete token '${token.id}?'`
   125                                                                      );
   126                                                                      if (!confirmed) {
   127                                                                          return;
   128                                                                      }
   129  
   130                                                                      try {
   131                                                                          await services.accounts.deleteToken(props.match.params.name, token.id);
   132                                                                          if (tokensLoaderRef.current) {
   133                                                                              tokensLoaderRef.current.reload();
   134                                                                          }
   135                                                                      } catch (e) {
   136                                                                          ctx.notifications.show({
   137                                                                              content: <ErrorNotification title='Unable to delete token token' e={e} />,
   138                                                                              type: NotificationType.Error
   139                                                                          });
   140                                                                      }
   141                                                                  }}
   142                                                              />
   143                                                          </div>
   144                                                      </div>
   145                                                  </div>
   146                                              ))}
   147                                          </div>
   148                                      )) || (
   149                                          <div className='white-box'>
   150                                              <p>Account has no tokens. Click 'Generate New' to create one.</p>
   151                                          </div>
   152                                      )
   153                                  }
   154                              </DataLoader>
   155                          </React.Fragment>
   156                      )}
   157                  </DataLoader>
   158              </div>
   159          </Page>
   160      );
   161  };