github.com/argoproj/argo-cd/v2@v2.10.9/ui/src/app/shared/components/paginate/paginate.tsx (about)

     1  import {DataLoader, DropDownMenu} from 'argo-ui';
     2  
     3  import * as React from 'react';
     4  import ReactPaginate from 'react-paginate';
     5  import {services} from '../../services';
     6  
     7  require('./paginate.scss');
     8  
     9  export interface SortOption<T> {
    10      title: string;
    11      compare: (a: T, b: T) => number;
    12  }
    13  
    14  export interface PaginateProps<T> {
    15      page: number;
    16      onPageChange: (page: number) => any;
    17      children: (data: T[]) => React.ReactNode;
    18      data: T[];
    19      emptyState?: () => React.ReactNode;
    20      preferencesKey?: string;
    21      header?: React.ReactNode;
    22      showHeader?: boolean;
    23      sortOptions?: SortOption<T>[];
    24  }
    25  
    26  export function Paginate<T>({page, onPageChange, children, data, emptyState, preferencesKey, header, showHeader, sortOptions}: PaginateProps<T>) {
    27      return (
    28          <DataLoader load={() => services.viewPreferences.getPreferences()}>
    29              {pref => {
    30                  preferencesKey = preferencesKey || 'default';
    31                  const pageSize = pref.pageSizes[preferencesKey] || 10;
    32                  const sortOption = sortOptions ? (pref.sortOptions && pref.sortOptions[preferencesKey]) || sortOptions[0].title : '';
    33                  const pageCount = pageSize === -1 ? 1 : Math.ceil(data.length / pageSize);
    34                  if (pageCount <= page) {
    35                      page = pageCount - 1;
    36                  }
    37  
    38                  function paginator() {
    39                      return (
    40                          <div style={{marginBottom: '0.5em'}}>
    41                              <div style={{display: 'flex', alignItems: 'center', marginBottom: '0.5em', paddingLeft: '1em'}}>
    42                                  {pageCount > 1 && (
    43                                      <ReactPaginate
    44                                          containerClassName='paginate__paginator'
    45                                          forcePage={page}
    46                                          pageCount={pageCount}
    47                                          pageRangeDisplayed={5}
    48                                          marginPagesDisplayed={2}
    49                                          onPageChange={item => onPageChange(item.selected)}
    50                                      />
    51                                  )}
    52                                  <div className='paginate__size-menu'>
    53                                      {sortOptions && (
    54                                          <DropDownMenu
    55                                              anchor={() => (
    56                                                  <>
    57                                                      <a>
    58                                                          Sort: {sortOption.toLowerCase()} <i className='fa fa-caret-down' />
    59                                                      </a>
    60                                                      &nbsp;
    61                                                  </>
    62                                              )}
    63                                              items={sortOptions.map(so => ({
    64                                                  title: so.title,
    65                                                  action: () => {
    66                                                      // sortOptions might not be set in the browser storage
    67                                                      if (!pref.sortOptions) {
    68                                                          pref.sortOptions = {};
    69                                                      }
    70                                                      pref.sortOptions[preferencesKey] = so.title;
    71                                                      services.viewPreferences.updatePreferences(pref);
    72                                                  }
    73                                              }))}
    74                                          />
    75                                      )}
    76                                      <DropDownMenu
    77                                          anchor={() => (
    78                                              <a>
    79                                                  Items per page: {pageSize === -1 ? 'all' : pageSize} <i className='fa fa-caret-down' />
    80                                              </a>
    81                                          )}
    82                                          items={[5, 10, 15, 20, -1].map(count => ({
    83                                              title: count === -1 ? 'all' : count.toString(),
    84                                              action: () => {
    85                                                  pref.pageSizes[preferencesKey] = count;
    86                                                  services.viewPreferences.updatePreferences(pref);
    87                                              }
    88                                          }))}
    89                                      />
    90                                  </div>
    91                              </div>
    92                              {showHeader && header}
    93                          </div>
    94                      );
    95                  }
    96                  if (sortOption) {
    97                      sortOptions
    98                          .filter(o => o.title === sortOption)
    99                          .forEach(so => {
   100                              data.sort(so.compare);
   101                          });
   102                  }
   103                  return (
   104                      <React.Fragment>
   105                          <div className='paginate'>{paginator()}</div>
   106                          {data.length === 0 && emptyState ? emptyState() : children(pageSize === -1 ? data : data.slice(pageSize * page, pageSize * (page + 1)))}
   107                          <div className='paginate'>{pageCount > 1 && paginator()}</div>
   108                      </React.Fragment>
   109                  );
   110              }}
   111          </DataLoader>
   112      );
   113  }