mirror of
https://github.com/strapi/strapi.git
synced 2025-09-27 09:25:46 +00:00
Merge branch 'main' of github.com:strapi/strapi into feature/market-sort-filters
This commit is contained in:
commit
b84fd921a6
7
.github/dependabot.yml
vendored
7
.github/dependabot.yml
vendored
@ -19,3 +19,10 @@ updates:
|
|||||||
labels:
|
labels:
|
||||||
- 'source: dependencies'
|
- 'source: dependencies'
|
||||||
- 'pr: chore'
|
- 'pr: chore'
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: daily
|
||||||
|
labels:
|
||||||
|
- 'source: dependencies'
|
||||||
|
- 'pr: chore'
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
import { Typography } from '@strapi/design-system/Typography';
|
||||||
|
import { Icon } from '@strapi/design-system/Icon';
|
||||||
|
import { Divider } from '@strapi/design-system/Divider';
|
||||||
|
import { Stack } from '@strapi/design-system/Stack';
|
||||||
|
import Github from '@strapi/icons/Github';
|
||||||
|
import Download from '@strapi/icons/Download';
|
||||||
|
import Star from '@strapi/icons/Star';
|
||||||
|
import { pxToRem } from '@strapi/helper-plugin';
|
||||||
|
|
||||||
|
const VerticalDivider = styled(Divider)`
|
||||||
|
width: ${pxToRem(12)};
|
||||||
|
transform: rotate(90deg);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const PackageStats = ({ githubStars, npmDownloads, npmPackageType }) => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack horizontal spacing={1}>
|
||||||
|
{!!githubStars && (
|
||||||
|
<>
|
||||||
|
<Icon as={Github} height={pxToRem(12)} width={pxToRem(12)} aria-hidden />
|
||||||
|
<Icon as={Star} height={pxToRem(12)} width={pxToRem(12)} color="warning500" aria-hidden />
|
||||||
|
<p
|
||||||
|
aria-label={formatMessage(
|
||||||
|
{
|
||||||
|
id: `admin.pages.MarketPlacePage.${npmPackageType}.githubStars`,
|
||||||
|
defaultMessage: `This {package} was starred {starsCount} on GitHub`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
starsCount: githubStars,
|
||||||
|
package: npmPackageType,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Typography variant="pi" textColor="neutral800" lineHeight={16}>
|
||||||
|
{githubStars}
|
||||||
|
</Typography>
|
||||||
|
</p>
|
||||||
|
<VerticalDivider unsetMargin={false} background="neutral200" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<Icon as={Download} height={pxToRem(12)} width={pxToRem(12)} aria-hidden />
|
||||||
|
<p
|
||||||
|
aria-label={formatMessage(
|
||||||
|
{
|
||||||
|
id: `admin.pages.MarketPlacePage.${npmPackageType}.downloads`,
|
||||||
|
defaultMessage: `This {package} has {downloadsCount} weekly downloads`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
downloadsCount: npmDownloads,
|
||||||
|
package: npmPackageType,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Typography variant="pi" textColor="neutral800" lineHeight={16}>
|
||||||
|
{npmDownloads}
|
||||||
|
</Typography>
|
||||||
|
</p>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
PackageStats.defaultProps = {
|
||||||
|
githubStars: 0,
|
||||||
|
npmDownloads: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
PackageStats.propTypes = {
|
||||||
|
githubStars: PropTypes.number,
|
||||||
|
npmDownloads: PropTypes.number,
|
||||||
|
npmPackageType: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PackageStats;
|
@ -15,6 +15,7 @@ import CheckCircle from '@strapi/icons/CheckCircle';
|
|||||||
import { useTracking } from '@strapi/helper-plugin';
|
import { useTracking } from '@strapi/helper-plugin';
|
||||||
import madeByStrapiIcon from '../../../../assets/images/icon_made-by-strapi.svg';
|
import madeByStrapiIcon from '../../../../assets/images/icon_made-by-strapi.svg';
|
||||||
import InstallPluginButton from './InstallPluginButton';
|
import InstallPluginButton from './InstallPluginButton';
|
||||||
|
import PackageStats from './PackageStats';
|
||||||
|
|
||||||
// Custom component to have an ellipsis after the 2nd line
|
// Custom component to have an ellipsis after the 2nd line
|
||||||
const EllipsisText = styled(Typography)`
|
const EllipsisText = styled(Typography)`
|
||||||
@ -67,14 +68,21 @@ const NpmPackageCard = ({
|
|||||||
data-testid="npm-package-card"
|
data-testid="npm-package-card"
|
||||||
>
|
>
|
||||||
<Box>
|
<Box>
|
||||||
<Box
|
<Flex direction="row" justifyContent="space-between" alignItems="flex-start">
|
||||||
as="img"
|
<Box
|
||||||
src={attributes.logo.url}
|
as="img"
|
||||||
alt={`${attributes.name} logo`}
|
src={attributes.logo.url}
|
||||||
hasRadius
|
alt={`${attributes.name} logo`}
|
||||||
width={11}
|
hasRadius
|
||||||
height={11}
|
width={11}
|
||||||
/>
|
height={11}
|
||||||
|
/>
|
||||||
|
<PackageStats
|
||||||
|
githubStars={attributes.githubStars}
|
||||||
|
npmDownloads={attributes.npmDownloads}
|
||||||
|
npmPackageType={npmPackageType}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
<Box paddingTop={4}>
|
<Box paddingTop={4}>
|
||||||
<Typography as="h3" variant="delta">
|
<Typography as="h3" variant="delta">
|
||||||
<Flex alignItems="center">
|
<Flex alignItems="center">
|
||||||
@ -170,6 +178,8 @@ NpmPackageCard.propTypes = {
|
|||||||
madeByStrapi: PropTypes.bool.isRequired,
|
madeByStrapi: PropTypes.bool.isRequired,
|
||||||
strapiCompatibility: PropTypes.oneOf(['v3', 'v4']),
|
strapiCompatibility: PropTypes.oneOf(['v3', 'v4']),
|
||||||
strapiVersion: PropTypes.string,
|
strapiVersion: PropTypes.string,
|
||||||
|
githubStars: PropTypes.number,
|
||||||
|
npmDownloads: PropTypes.number,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
isInstalled: PropTypes.bool.isRequired,
|
isInstalled: PropTypes.bool.isRequired,
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, waitFor, screen, getByRole, fireEvent } from '@testing-library/react';
|
import {
|
||||||
|
render,
|
||||||
|
waitFor,
|
||||||
|
screen,
|
||||||
|
getByRole,
|
||||||
|
fireEvent,
|
||||||
|
queryByLabelText,
|
||||||
|
getByLabelText,
|
||||||
|
} from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||||
@ -173,4 +181,31 @@ describe('Marketplace page - layout', () => {
|
|||||||
// Should not show install buttons
|
// Should not show install buttons
|
||||||
expect(screen.queryByText(/copy install command/i)).toEqual(null);
|
expect(screen.queryByText(/copy install command/i)).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows only downloads count and not github stars if there are no or 0 stars and no downloads available for any package', async () => {
|
||||||
|
client.clear();
|
||||||
|
render(App);
|
||||||
|
|
||||||
|
await waitForReload();
|
||||||
|
|
||||||
|
const providersTab = screen.getByRole('tab', { name: /providers/i });
|
||||||
|
userEvent.click(providersTab);
|
||||||
|
|
||||||
|
const nodeMailerCard = screen
|
||||||
|
.getAllByTestId('npm-package-card')
|
||||||
|
.find((div) => div.innerHTML.includes('Nodemailer'));
|
||||||
|
|
||||||
|
const githubStarsLabel = queryByLabelText(
|
||||||
|
nodeMailerCard,
|
||||||
|
/this provider was starred \d+ on GitHub/i
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(githubStarsLabel).toBe(null);
|
||||||
|
|
||||||
|
const downloadsLabel = getByLabelText(
|
||||||
|
nodeMailerCard,
|
||||||
|
/this provider has \d+ weekly downloads/i
|
||||||
|
);
|
||||||
|
expect(downloadsLabel).toBeVisible();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -39,6 +39,9 @@ const plugins = {
|
|||||||
validated: false,
|
validated: false,
|
||||||
madeByStrapi: false,
|
madeByStrapi: false,
|
||||||
strapiCompatibility: 'v3',
|
strapiCompatibility: 'v3',
|
||||||
|
strapiVersion: '^4.0.0',
|
||||||
|
githubStars: 23,
|
||||||
|
npmDownloads: 5623,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -212,6 +215,9 @@ const plugins = {
|
|||||||
validated: false,
|
validated: false,
|
||||||
madeByStrapi: false,
|
madeByStrapi: false,
|
||||||
strapiCompatibility: 'v4',
|
strapiCompatibility: 'v4',
|
||||||
|
strapiVersion: '4.x.x',
|
||||||
|
githubStars: 323,
|
||||||
|
npmDownloads: 1123,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -282,6 +288,7 @@ const plugins = {
|
|||||||
validated: true,
|
validated: true,
|
||||||
madeByStrapi: false,
|
madeByStrapi: false,
|
||||||
strapiCompatibility: 'v4',
|
strapiCompatibility: 'v4',
|
||||||
|
strapiVersion: 'Contact developer',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -352,6 +359,7 @@ const plugins = {
|
|||||||
validated: false,
|
validated: false,
|
||||||
madeByStrapi: false,
|
madeByStrapi: false,
|
||||||
strapiCompatibility: 'v4',
|
strapiCompatibility: 'v4',
|
||||||
|
strapiVersion: '^3.4.2',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -394,6 +402,9 @@ const plugins = {
|
|||||||
validated: true,
|
validated: true,
|
||||||
madeByStrapi: true,
|
madeByStrapi: true,
|
||||||
strapiCompatibility: 'v4',
|
strapiCompatibility: 'v4',
|
||||||
|
strapiVersion: '^4.0.7',
|
||||||
|
githubStars: 49130,
|
||||||
|
npmDownloads: 7492,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -436,6 +447,7 @@ const plugins = {
|
|||||||
validated: true,
|
validated: true,
|
||||||
madeByStrapi: false,
|
madeByStrapi: false,
|
||||||
strapiCompatibility: 'v3',
|
strapiCompatibility: 'v3',
|
||||||
|
strapiVersion: '^4.3.0',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -126,6 +126,8 @@ const providers = {
|
|||||||
validated: true,
|
validated: true,
|
||||||
madeByStrapi: true,
|
madeByStrapi: true,
|
||||||
strapiCompatibility: 'v4',
|
strapiCompatibility: 'v4',
|
||||||
|
githubStars: 49130,
|
||||||
|
npmDownloads: 7492,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -168,6 +170,8 @@ const providers = {
|
|||||||
developerName: 'Strapi team',
|
developerName: 'Strapi team',
|
||||||
validated: true,
|
validated: true,
|
||||||
madeByStrapi: true,
|
madeByStrapi: true,
|
||||||
|
githubStars: 30,
|
||||||
|
npmDownloads: 2492,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
screen,
|
screen,
|
||||||
getByText,
|
getByText,
|
||||||
queryByText,
|
queryByText,
|
||||||
|
getByLabelText,
|
||||||
} from '@testing-library/react';
|
} from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
@ -403,4 +404,23 @@ describe('Marketplace page - plugins tab', () => {
|
|||||||
userEvent.click(newestOption);
|
userEvent.click(newestOption);
|
||||||
expect(history.location.search).toEqual('?sort=submissionDate:desc');
|
expect(history.location.search).toEqual('?sort=submissionDate:desc');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows github stars and weekly downloads count for each plugin', () => {
|
||||||
|
const documentationCard = screen
|
||||||
|
.getAllByTestId('npm-package-card')
|
||||||
|
.find((div) => div.innerHTML.includes('Documentation'));
|
||||||
|
|
||||||
|
const githubStarsLabel = getByLabelText(
|
||||||
|
documentationCard,
|
||||||
|
/this plugin was starred \d+ on GitHub/i
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(githubStarsLabel).toBeVisible();
|
||||||
|
|
||||||
|
const downloadsLabel = getByLabelText(
|
||||||
|
documentationCard,
|
||||||
|
/this plugin has \d+ weekly downloads/i
|
||||||
|
);
|
||||||
|
expect(downloadsLabel).toBeVisible();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
screen,
|
screen,
|
||||||
getByText,
|
getByText,
|
||||||
queryByText,
|
queryByText,
|
||||||
|
getByLabelText,
|
||||||
} from '@testing-library/react';
|
} from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
@ -298,4 +299,25 @@ describe('Marketplace page - providers tab', () => {
|
|||||||
userEvent.click(newestOption);
|
userEvent.click(newestOption);
|
||||||
expect(history.location.search).toEqual('?npmPackageType=provider&sort=submissionDate:desc');
|
expect(history.location.search).toEqual('?npmPackageType=provider&sort=submissionDate:desc');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows github stars and weekly downloads count for each provider', () => {
|
||||||
|
const providersTab = screen.getByRole('tab', { name: /providers/i });
|
||||||
|
userEvent.click(providersTab);
|
||||||
|
|
||||||
|
const cloudinaryCard = screen
|
||||||
|
.getAllByTestId('npm-package-card')
|
||||||
|
.find((div) => div.innerHTML.includes('Cloudinary'));
|
||||||
|
|
||||||
|
const githubStarsLabel = getByLabelText(
|
||||||
|
cloudinaryCard,
|
||||||
|
/this provider was starred \d+ on GitHub/i
|
||||||
|
);
|
||||||
|
expect(githubStarsLabel).toBeVisible();
|
||||||
|
|
||||||
|
const downloadsLabel = getByLabelText(
|
||||||
|
cloudinaryCard,
|
||||||
|
/this provider has \d+ weekly downloads/i
|
||||||
|
);
|
||||||
|
expect(downloadsLabel).toBeVisible();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -272,7 +272,11 @@
|
|||||||
"admin.pages.MarketPlacePage.plugin.tooltip.verified": "Plugin verified by Strapi",
|
"admin.pages.MarketPlacePage.plugin.tooltip.verified": "Plugin verified by Strapi",
|
||||||
"admin.pages.MarketPlacePage.plugin.version": "Update your Strapi version: \"{strapiAppVersion}\" to: \"{versionRange}\"",
|
"admin.pages.MarketPlacePage.plugin.version": "Update your Strapi version: \"{strapiAppVersion}\" to: \"{versionRange}\"",
|
||||||
"admin.pages.MarketPlacePage.plugin.version.null": "Unable to verify compatibility with your Strapi version: \"{strapiAppVersion}\"",
|
"admin.pages.MarketPlacePage.plugin.version.null": "Unable to verify compatibility with your Strapi version: \"{strapiAppVersion}\"",
|
||||||
|
"admin.pages.MarketPlacePage.plugin.githubStars": "This plugin was starred {starsCount} on GitHub",
|
||||||
|
"admin.pages.MarketPlacePage.plugin.downloads": "This plugin has {downloadsCount} weekly downloads",
|
||||||
"admin.pages.MarketPlacePage.providers": "Providers",
|
"admin.pages.MarketPlacePage.providers": "Providers",
|
||||||
|
"admin.pages.MarketPlacePage.provider.githubStars": "This provider was starred {starsCount} on GitHub",
|
||||||
|
"admin.pages.MarketPlacePage.provider.downloads": "This provider has {downloadsCount} weekly downloads",
|
||||||
"admin.pages.MarketPlacePage.search.clear": "Clear the search",
|
"admin.pages.MarketPlacePage.search.clear": "Clear the search",
|
||||||
"admin.pages.MarketPlacePage.search.empty": "No result for \"{target}\"",
|
"admin.pages.MarketPlacePage.search.empty": "No result for \"{target}\"",
|
||||||
"admin.pages.MarketPlacePage.search.placeholder": "Search",
|
"admin.pages.MarketPlacePage.search.placeholder": "Search",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user