mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 01:47:13 +00:00 
			
		
		
		
	Add pagination to marketplace
This commit is contained in:
		
							parent
							
								
									6e2d0db457
								
							
						
					
					
						commit
						048e5a2f4e
					
				| @ -1,10 +1,12 @@ | |||||||
| import axios from 'axios'; | import axios from 'axios'; | ||||||
|  | import qs from 'qs'; | ||||||
| 
 | 
 | ||||||
| const MARKETPLACE_API_URL = 'https://market-api.strapi.io'; | const MARKETPLACE_API_URL = 'https://market-api.strapi.io'; | ||||||
| 
 | 
 | ||||||
| const fetchMarketplacePlugins = async (params = {}) => { | const fetchMarketplacePlugins = async (params = {}) => { | ||||||
|   const { data: response } = await axios.get(`${MARKETPLACE_API_URL}/plugins`, { |   const { data: response } = await axios.get(`${MARKETPLACE_API_URL}/plugins`, { | ||||||
|     params, |     params, | ||||||
|  |     paramsSerializer: (params) => qs.stringify(params), | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   // Only keep v4 plugins
 |   // Only keep v4 plugins
 | ||||||
|  | |||||||
| @ -0,0 +1,27 @@ | |||||||
|  | import React from 'react'; | ||||||
|  | import PropTypes from 'prop-types'; | ||||||
|  | import { Box } from '@strapi/design-system/Box'; | ||||||
|  | import { Flex } from '@strapi/design-system/Flex'; | ||||||
|  | import { PaginationURLQuery, PageSizeURLQuery } from '@strapi/helper-plugin'; | ||||||
|  | 
 | ||||||
|  | const NpmPackagesPagination = ({ pagination }) => { | ||||||
|  |   return ( | ||||||
|  |     <Box paddingTop={4}> | ||||||
|  |       <Flex alignItems="flex-end" justifyContent="space-between"> | ||||||
|  |         <PageSizeURLQuery options={['12', '24', '50', '100']} defaultValue="24" /> | ||||||
|  |         <PaginationURLQuery pagination={pagination} /> | ||||||
|  |       </Flex> | ||||||
|  |     </Box> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | NpmPackagesPagination.propTypes = { | ||||||
|  |   pagination: PropTypes.shape({ | ||||||
|  |     page: PropTypes.number.isRequired, | ||||||
|  |     pageCount: PropTypes.number.isRequired, | ||||||
|  |     pageSize: PropTypes.number.isRequired, | ||||||
|  |     total: PropTypes.number.isRequired, | ||||||
|  |   }).isRequired, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default NpmPackagesPagination; | ||||||
| @ -39,6 +39,7 @@ import MissingPluginBanner from './components/MissingPluginBanner'; | |||||||
| import NpmPackagesGrid from './components/NpmPackagesGrid'; | import NpmPackagesGrid from './components/NpmPackagesGrid'; | ||||||
| import SortSelect from './components/SortSelect'; | import SortSelect from './components/SortSelect'; | ||||||
| import NpmPackagesFilters from './components/NpmPackagesFilters'; | import NpmPackagesFilters from './components/NpmPackagesFilters'; | ||||||
|  | import NpmPackagesPagination from './components/NpmPackagesPagination'; | ||||||
| 
 | 
 | ||||||
| const matchSearch = (npmPackages, search) => { | const matchSearch = (npmPackages, search) => { | ||||||
|   return matchSorter(npmPackages, search, { |   return matchSorter(npmPackages, search, { | ||||||
| @ -67,6 +68,11 @@ const MarketPlacePage = () => { | |||||||
| 
 | 
 | ||||||
|   const npmPackageType = query?.npmPackageType || 'plugin'; |   const npmPackageType = query?.npmPackageType || 'plugin'; | ||||||
| 
 | 
 | ||||||
|  |   const paginationParams = { | ||||||
|  |     page: query?.page || 1, | ||||||
|  |     pageSize: query?.pageSize || 24, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   const [tabQuery, setTabQuery] = useState({ |   const [tabQuery, setTabQuery] = useState({ | ||||||
|     plugin: npmPackageType === 'plugin' ? { ...query } : {}, |     plugin: npmPackageType === 'plugin' ? { ...query } : {}, | ||||||
|     provider: npmPackageType === 'provider' ? { ...query } : {}, |     provider: npmPackageType === 'provider' ? { ...query } : {}, | ||||||
| @ -92,10 +98,16 @@ const MarketPlacePage = () => { | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const { status: marketplaceProvidersStatus, data: marketplaceProvidersResponse } = |   const { status: marketplaceProvidersStatus, data: marketplaceProvidersResponse } = | ||||||
|     useFetchMarketplaceProviders(notifyMarketplaceLoad, tabQuery.provider); |     useFetchMarketplaceProviders(notifyMarketplaceLoad, { | ||||||
|  |       ...tabQuery.provider, | ||||||
|  |       pagination: paginationParams, | ||||||
|  |     }); | ||||||
| 
 | 
 | ||||||
|   const { status: marketplacePluginsStatus, data: marketplacePluginsResponse } = |   const { status: marketplacePluginsStatus, data: marketplacePluginsResponse } = | ||||||
|     useFetchMarketplacePlugins(notifyMarketplaceLoad, tabQuery.plugin); |     useFetchMarketplacePlugins(notifyMarketplaceLoad, { | ||||||
|  |       ...tabQuery.plugin, | ||||||
|  |       pagination: paginationParams, | ||||||
|  |     }); | ||||||
| 
 | 
 | ||||||
|   const isLoading = [marketplacePluginsStatus, marketplaceProvidersStatus].includes('loading'); |   const isLoading = [marketplacePluginsStatus, marketplaceProvidersStatus].includes('loading'); | ||||||
| 
 | 
 | ||||||
| @ -192,7 +204,7 @@ const MarketPlacePage = () => { | |||||||
|     const hasTabQuery = tabQuery[selectedTab] && Object.keys(tabQuery[selectedTab]).length; |     const hasTabQuery = tabQuery[selectedTab] && Object.keys(tabQuery[selectedTab]).length; | ||||||
| 
 | 
 | ||||||
|     if (hasTabQuery) { |     if (hasTabQuery) { | ||||||
|       setQuery({ ...tabQuery[selectedTab], npmPackageType: selectedTab }); |       setQuery({ ...tabQuery[selectedTab], npmPackageType: selectedTab, page: 1 }); | ||||||
|     } else { |     } else { | ||||||
|       setQuery({ |       setQuery({ | ||||||
|         npmPackageType: selectedTab, |         npmPackageType: selectedTab, | ||||||
| @ -200,6 +212,7 @@ const MarketPlacePage = () => { | |||||||
|         collections: [], |         collections: [], | ||||||
|         categories: [], |         categories: [], | ||||||
|         sort: 'name:asc', |         sort: 'name:asc', | ||||||
|  |         page: 1, | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| @ -226,6 +239,11 @@ const MarketPlacePage = () => { | |||||||
|       : marketplaceProvidersResponse.meta.collections; |       : marketplaceProvidersResponse.meta.collections; | ||||||
|   const possibleCategories = marketplacePluginsResponse.meta.categories; |   const possibleCategories = marketplacePluginsResponse.meta.categories; | ||||||
| 
 | 
 | ||||||
|  |   const { pagination } = | ||||||
|  |     npmPackageType === 'plugin' | ||||||
|  |       ? marketplacePluginsResponse.meta | ||||||
|  |       : marketplaceProvidersResponse.meta; | ||||||
|  | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Layout> |     <Layout> | ||||||
|       <Main> |       <Main> | ||||||
| @ -333,7 +351,8 @@ const MarketPlacePage = () => { | |||||||
|               </TabPanel> |               </TabPanel> | ||||||
|             </TabPanels> |             </TabPanels> | ||||||
|           </TabGroup> |           </TabGroup> | ||||||
|           <Box paddingTop={7}> |           <NpmPackagesPagination pagination={pagination} /> | ||||||
|  |           <Box paddingTop={8}> | ||||||
|             <MissingPluginBanner /> |             <MissingPluginBanner /> | ||||||
|           </Box> |           </Box> | ||||||
|         </ContentLayout> |         </ContentLayout> | ||||||
|  | |||||||
| @ -3,6 +3,14 @@ import { rest } from 'msw'; | |||||||
| import { responses as pluginResponses } from './mocks/plugins'; | import { responses as pluginResponses } from './mocks/plugins'; | ||||||
| import { responses as providerResponses } from './mocks/providers'; | import { responses as providerResponses } from './mocks/providers'; | ||||||
| 
 | 
 | ||||||
|  | rest.get('https://market-api.strapi.io/plugins?collections[]', (req, res, ctx) => { | ||||||
|  |   return { | ||||||
|  |     data: [ | ||||||
|  |        | ||||||
|  |     ] | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| const handlers = [ | const handlers = [ | ||||||
|   rest.get('https://market-api.strapi.io/plugins', (req, res, ctx) => { |   rest.get('https://market-api.strapi.io/plugins', (req, res, ctx) => { | ||||||
|     let responseData; |     let responseData; | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ import PropTypes from 'prop-types'; | |||||||
| import useQueryParams from '../../hooks/useQueryParams'; | import useQueryParams from '../../hooks/useQueryParams'; | ||||||
| import useTracking from '../../hooks/useTracking'; | import useTracking from '../../hooks/useTracking'; | ||||||
| 
 | 
 | ||||||
| const PageSizeURLQuery = ({ trackedEvent }) => { | const PageSizeURLQuery = ({ trackedEvent, options, defaultValue }) => { | ||||||
|   const { formatMessage } = useIntl(); |   const { formatMessage } = useIntl(); | ||||||
|   const [{ query }, setQuery] = useQueryParams(); |   const [{ query }, setQuery] = useQueryParams(); | ||||||
|   const { trackUsage } = useTracking(); |   const { trackUsage } = useTracking(); | ||||||
| @ -26,7 +26,7 @@ const PageSizeURLQuery = ({ trackedEvent }) => { | |||||||
|       page: 1, |       page: 1, | ||||||
|     }); |     }); | ||||||
|   }; |   }; | ||||||
|   const pageSize = query?.pageSize || '10'; |   const pageSize = query?.pageSize || defaultValue; | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Flex> |     <Flex> | ||||||
| @ -39,10 +39,11 @@ const PageSizeURLQuery = ({ trackedEvent }) => { | |||||||
|         onChange={handleChange} |         onChange={handleChange} | ||||||
|         value={pageSize} |         value={pageSize} | ||||||
|       > |       > | ||||||
|         <Option value="10">10</Option> |         {options.map((option) => ( | ||||||
|         <Option value="20">20</Option> |           <Option key={option} value={option}> | ||||||
|         <Option value="50">50</Option> |             {option} | ||||||
|         <Option value="100">100</Option> |           </Option> | ||||||
|  |         ))} | ||||||
|       </Select> |       </Select> | ||||||
|       <Box paddingLeft={2}> |       <Box paddingLeft={2}> | ||||||
|         <Typography textColor="neutral600" as="label" htmlFor="page-size"> |         <Typography textColor="neutral600" as="label" htmlFor="page-size"> | ||||||
| @ -58,10 +59,14 @@ const PageSizeURLQuery = ({ trackedEvent }) => { | |||||||
| 
 | 
 | ||||||
| PageSizeURLQuery.defaultProps = { | PageSizeURLQuery.defaultProps = { | ||||||
|   trackedEvent: null, |   trackedEvent: null, | ||||||
|  |   options: ['10', '20', '50', '100'], | ||||||
|  |   defaultValue: '10', | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| PageSizeURLQuery.propTypes = { | PageSizeURLQuery.propTypes = { | ||||||
|   trackedEvent: PropTypes.string, |   trackedEvent: PropTypes.string, | ||||||
|  |   options: PropTypes.arrayOf(PropTypes.string.isRequired), | ||||||
|  |   defaultValue: PropTypes.string, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default PageSizeURLQuery; | export default PageSizeURLQuery; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Rémi de Juvigny
						Rémi de Juvigny