Add sort menu to the marketplace page

This commit is contained in:
Fernando Chavez 2022-10-06 08:51:50 -04:00
parent 2ea599327d
commit b82cd7d05a
6 changed files with 58 additions and 12 deletions

View File

@ -2,10 +2,10 @@ import { useQuery } from 'react-query';
import { useNotification } from '@strapi/helper-plugin'; import { useNotification } from '@strapi/helper-plugin';
import { fetchMarketplacePlugins } from './utils/api'; import { fetchMarketplacePlugins } from './utils/api';
const useFetchMarketplacePlugins = (notifyLoad) => { const useFetchMarketplacePlugins = (notifyLoad, sort) => {
const toggleNotification = useNotification(); const toggleNotification = useNotification();
return useQuery('list-marketplace-plugins', () => fetchMarketplacePlugins(), { return useQuery(['list-marketplace-plugins', sort], () => fetchMarketplacePlugins({ sort }), {
onSuccess() { onSuccess() {
if (notifyLoad) { if (notifyLoad) {
notifyLoad(); notifyLoad();

View File

@ -1,9 +1,13 @@
import axios from 'axios'; import axios from 'axios';
const MARKETPLACE_API_URL = 'https://market-api.strapi.io'; const MARKETPLACE_API_URL = 'https://market-api-proxy.herokuapp.com';
const fetchMarketplacePlugins = async () => { const fetchMarketplacePlugins = async ({ sort = 'name:asc' } = null) => {
const { data: response } = await axios.get(`${MARKETPLACE_API_URL}/plugins`); const { data: response } = await axios.get(`${MARKETPLACE_API_URL}/plugins`, {
params: {
sort,
},
});
// Only keep v4 plugins // Only keep v4 plugins
const filteredResponse = { const filteredResponse = {

View File

@ -2,10 +2,10 @@ import { useQuery } from 'react-query';
import { useNotification } from '@strapi/helper-plugin'; import { useNotification } from '@strapi/helper-plugin';
import { fetchMarketplacePlugins } from './utils/api'; import { fetchMarketplacePlugins } from './utils/api';
const useFetchMarketplaceProviders = (notifyLoad) => { const useFetchMarketplaceProviders = (notifyLoad, sort) => {
const toggleNotification = useNotification(); const toggleNotification = useNotification();
return useQuery('list-marketplace-providers', () => fetchMarketplacePlugins(), { return useQuery(['list-marketplace-providers', sort], () => fetchMarketplacePlugins({ sort }), {
onSuccess() { onSuccess() {
if (notifyLoad) { if (notifyLoad) {
notifyLoad(); notifyLoad();

View File

@ -2,8 +2,12 @@ import axios from 'axios';
const MARKETPLACE_API_URL = 'https://market-api.strapi.io'; const MARKETPLACE_API_URL = 'https://market-api.strapi.io';
const fetchMarketplacePlugins = async () => { const fetchMarketplacePlugins = async ({ sort = 'name:asc' } = null) => {
const { data } = await axios.get(`${MARKETPLACE_API_URL}/providers`); const { data } = await axios.get(`${MARKETPLACE_API_URL}/providers`, {
params: {
sort,
},
});
return data; return data;
}; };

View File

@ -0,0 +1,28 @@
import React from 'react';
import { SimpleMenu, MenuItem } from '@strapi/design-system/SimpleMenu';
import { useIntl } from 'react-intl';
import { NavLink } from 'react-router-dom';
import { getTrad } from '../../../../content-manager/utils';
const SortFilter = () => {
const { formatMessage } = useIntl();
return (
<SimpleMenu
variant="tertiary"
label={formatMessage({
id: getTrad('sort.label'),
defaultMessage: 'Sort by',
})}
>
<MenuItem as={NavLink} to="/marketplace?sort=name:asc">
Alphabetical Order
</MenuItem>
<MenuItem as={NavLink} to="/marketplace?sort=submissionDate:desc">
Newest
</MenuItem>
</SimpleMenu>
);
};
export default SortFilter;

View File

@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState, useMemo } from 'react';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import matchSorter from 'match-sorter'; import matchSorter from 'match-sorter';
@ -20,6 +20,7 @@ import { Typography } from '@strapi/design-system/Typography';
import { Flex } from '@strapi/design-system/Flex'; import { Flex } from '@strapi/design-system/Flex';
import { Tabs, Tab, TabGroup, TabPanels, TabPanel } from '@strapi/design-system/Tabs'; import { Tabs, Tab, TabGroup, TabPanels, TabPanel } from '@strapi/design-system/Tabs';
import { useLocation } from 'react-router-dom';
import EmptyNpmPackageSearch from './components/EmptyNpmPackageSearch'; import EmptyNpmPackageSearch from './components/EmptyNpmPackageSearch';
import PageHeader from './components/PageHeader'; import PageHeader from './components/PageHeader';
import useFetchMarketplaceProviders from '../../hooks/useFetchMarketplaceProviders'; import useFetchMarketplaceProviders from '../../hooks/useFetchMarketplaceProviders';
@ -29,6 +30,7 @@ import offlineCloud from '../../assets/images/icon_offline-cloud.svg';
import useNavigatorOnLine from '../../hooks/useNavigatorOnLine'; import useNavigatorOnLine from '../../hooks/useNavigatorOnLine';
import MissingPluginBanner from './components/MissingPluginBanner'; import MissingPluginBanner from './components/MissingPluginBanner';
import NpmPackagesGrid from './components/NpmPackagesGrid'; import NpmPackagesGrid from './components/NpmPackagesGrid';
import SortFilter from './components/SortFilter';
const matchSearch = (npmPackages, search) => { const matchSearch = (npmPackages, search) => {
return matchSorter(npmPackages, search, { return matchSorter(npmPackages, search, {
@ -39,6 +41,8 @@ const matchSearch = (npmPackages, search) => {
}, },
{ threshold: matchSorter.rankings.WORD_STARTS_WITH, key: 'attributes.description' }, { threshold: matchSorter.rankings.WORD_STARTS_WITH, key: 'attributes.description' },
], ],
sorter: (items) => items,
baseSort: (a, b) => (a.index < b.index ? -1 : 1),
}); });
}; };
@ -52,6 +56,9 @@ const MarketPlacePage = () => {
const [npmPackageType, setNpmPackageType] = useState('plugin'); const [npmPackageType, setNpmPackageType] = useState('plugin');
const { autoReload: isInDevelopmentMode, dependencies, useYarn } = useAppInfos(); const { autoReload: isInDevelopmentMode, dependencies, useYarn } = useAppInfos();
const isOnline = useNavigatorOnLine(); const isOnline = useNavigatorOnLine();
const { search } = useLocation();
const params = useMemo(() => new URLSearchParams(search), [search]);
const sort = params.get('sort') || 'name:asc';
useFocusWhenNavigate(); useFocusWhenNavigate();
@ -73,10 +80,10 @@ const MarketPlacePage = () => {
}; };
const { status: marketplacePluginsStatus, data: marketplacePluginsResponse } = const { status: marketplacePluginsStatus, data: marketplacePluginsResponse } =
useFetchMarketplacePlugins(notifyMarketplaceLoad); useFetchMarketplacePlugins(notifyMarketplaceLoad, sort);
const { status: marketplaceProvidersStatus, data: marketplaceProvidersResponse } = const { status: marketplaceProvidersStatus, data: marketplaceProvidersResponse } =
useFetchMarketplaceProviders(notifyMarketplaceLoad); useFetchMarketplaceProviders(notifyMarketplaceLoad, sort);
const isLoading = [marketplacePluginsStatus, marketplaceProvidersStatus].includes('loading'); const isLoading = [marketplacePluginsStatus, marketplaceProvidersStatus].includes('loading');
@ -235,6 +242,9 @@ const MarketPlacePage = () => {
</Tab> </Tab>
</Tabs> </Tabs>
</Box> </Box>
<Box paddingBottom={4}>
<SortFilter />
</Box>
<TabPanels> <TabPanels>
{/* Plugins panel */} {/* Plugins panel */}
<TabPanel> <TabPanel>