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

     1  import {FormField, NotificationType, SlidingPanel} from 'argo-ui';
     2  import React, {useRef, useContext} from 'react';
     3  import {Form, FormApi, Text} from 'react-form';
     4  
     5  import {DataLoader, EmptyState, ErrorNotification, Page, Query} from '../../../shared/components';
     6  import {Context} from '../../../shared/context';
     7  import {Project} from '../../../shared/models';
     8  import {services} from '../../../shared/services';
     9  
    10  export function ProjectsList() {
    11      const formApiRef = useRef<FormApi | null>(null);
    12      const ctx = useContext(Context);
    13  
    14      return (
    15          <Page
    16              title='Projects'
    17              toolbar={{
    18                  breadcrumbs: [{title: 'Settings', path: '/settings'}, {title: 'Projects'}],
    19                  actionMenu: {
    20                      className: 'fa fa-plus',
    21                      items: [{title: 'New Project', iconClassName: 'fa fa-plus', action: () => ctx.navigation.goto('.', {add: true}, {replace: true})}]
    22                  }
    23              }}>
    24              <div className='projects argo-container'>
    25                  <DataLoader load={() => services.projects.list()}>
    26                      {projects =>
    27                          (projects.length > 0 && (
    28                              <div className='argo-table-list argo-table-list--clickable'>
    29                                  <div className='argo-table-list__head'>
    30                                      <div className='row'>
    31                                          <div className='columns small-3'>NAME</div>
    32                                          <div className='columns small-6'>DESCRIPTION</div>
    33                                      </div>
    34                                  </div>
    35                                  {projects.map(proj => (
    36                                      <div className='argo-table-list__row' key={proj.metadata.name} onClick={() => ctx.navigation.goto(`./${proj.metadata.name}`)}>
    37                                          <div className='row'>
    38                                              <div className='columns small-3'>
    39                                                  <i className='fa fa-object-group' /> {proj.metadata.name}
    40                                              </div>
    41                                              <div className='columns small-6'>{proj.spec.description}</div>
    42                                          </div>
    43                                      </div>
    44                                  ))}
    45                              </div>
    46                          )) || (
    47                              <EmptyState icon='fa fa-object-group'>
    48                                  <h4>No projects yet</h4>
    49                                  <h5>Create new projects to group your applications</h5>
    50                                  <button className='argo-button argo-button--base' onClick={() => ctx.navigation.goto('.', {add: true}, {replace: true})}>
    51                                      New project
    52                                  </button>
    53                              </EmptyState>
    54                          )
    55                      }
    56                  </DataLoader>
    57              </div>
    58              <Query>
    59                  {params => (
    60                      <SlidingPanel
    61                          isShown={params.get('add') === 'true'}
    62                          onClose={() => ctx.navigation.goto('.', {add: null}, {replace: true})}
    63                          isMiddle={true}
    64                          header={
    65                              <div>
    66                                  <button onClick={() => formApiRef.current && formApiRef.current.submitForm(null)} className='argo-button argo-button--base'>
    67                                      Create
    68                                  </button>{' '}
    69                                  <button onClick={() => ctx.navigation.goto('.', {add: null}, {replace: true})} className='argo-button argo-button--base-o'>
    70                                      Cancel
    71                                  </button>
    72                              </div>
    73                          }>
    74                          <Form
    75                              defaultValues={{metadata: {}, spec: {}}}
    76                              getApi={api => (formApiRef.current = api)}
    77                              validateError={(p: Project) => ({
    78                                  'metadata.name': !p.metadata.name && 'Project Name is required'
    79                              })}
    80                              onSubmit={async (proj: Project) => {
    81                                  try {
    82                                      await services.projects.create(proj);
    83                                      ctx.navigation.goto(`./${proj.metadata.name}`, {add: null}, {replace: true});
    84                                  } catch (e) {
    85                                      ctx.notifications.show({
    86                                          content: <ErrorNotification title='Unable to create project' e={e} />,
    87                                          type: NotificationType.Error
    88                                      });
    89                                  }
    90                              }}>
    91                              {api => (
    92                                  <form onSubmit={api.submitForm} role='form' className='width-control'>
    93                                      <div className='white-box'>
    94                                          <p>GENERAL</p>
    95                                          <div className='argo-form-row'>
    96                                              <FormField formApi={api} label='Project Name' field='metadata.name' component={Text} />
    97                                          </div>
    98                                          <div className='argo-form-row'>
    99                                              <FormField formApi={api} label='Description' field='spec.description' component={Text} />
   100                                          </div>
   101                                      </div>
   102                                  </form>
   103                              )}
   104                          </Form>
   105                      </SlidingPanel>
   106                  )}
   107              </Query>
   108          </Page>
   109      );
   110  }