Add pagination to marketplace

This commit is contained in:
Rémi de Juvigny 2022-11-11 17:07:17 +01:00 committed by Fernando Chavez
parent 6e2d0db457
commit 048e5a2f4e
5 changed files with 71 additions and 10 deletions

View File

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

View File

@ -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;

View File

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

View File

@ -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;

View File

@ -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;