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 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 }