mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 16:29:34 +00:00
Merge pull request #12556 from strapi/market-list-plugins
List plugins on in-app marketplace
This commit is contained in:
commit
a7fec64fc4
@ -1,7 +1,6 @@
|
||||
export { default as useConfigurations } from './useConfigurations';
|
||||
export { default as useModels } from './useModels';
|
||||
export { default as useFetchPermissionsLayout } from './useFetchPermissionsLayout';
|
||||
export { default as useFetchPluginsFromMarketPlace } from './useFetchPluginsFromMarketPlace';
|
||||
export { default as useFetchRole } from './useFetchRole';
|
||||
export { default as useMenu } from './useMenu';
|
||||
export { default as useRolesList } from './useRolesList';
|
||||
|
@ -1,49 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import { useIntl } from 'react-intl';
|
||||
|
||||
const useFetchPluginsFromMarketPlace = () => {
|
||||
const { locale: currentLocale } = useIntl();
|
||||
const [state, setState] = useState({
|
||||
error: false,
|
||||
isLoading: true,
|
||||
data: null,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const CancelToken = axios.CancelToken;
|
||||
const source = CancelToken.source();
|
||||
|
||||
const getData = async () => {
|
||||
try {
|
||||
const { data } = await axios.get('https://marketplace.strapi.io/plugins', {
|
||||
cancelToken: source.token,
|
||||
params: { lang: currentLocale },
|
||||
});
|
||||
|
||||
setState({
|
||||
isLoading: false,
|
||||
data,
|
||||
error: false,
|
||||
});
|
||||
} catch (err) {
|
||||
if (axios.isCancel(err)) {
|
||||
// Silent
|
||||
} else {
|
||||
// handle error
|
||||
setState(prev => ({ ...prev, isLoading: false, error: true }));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getData();
|
||||
|
||||
return () => {
|
||||
source.cancel();
|
||||
};
|
||||
}, [currentLocale]);
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
export default useFetchPluginsFromMarketPlace;
|
@ -1,46 +0,0 @@
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import axios from 'axios';
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
|
||||
import useFetch from '../index';
|
||||
|
||||
jest.mock('react-intl', () => ({ useIntl: () => ({ locale: 'en' }) }));
|
||||
|
||||
describe('ADMIN | hooks | useFetchPluginsFromMarketPlace', () => {
|
||||
it('should perform a GET request', async () => {
|
||||
const mock = new MockAdapter(axios);
|
||||
const mockData = [{ ok: true }];
|
||||
mock.onGet().replyOnce(200, mockData);
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() => useFetch());
|
||||
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.isLoading).toBeFalsy();
|
||||
expect(result.current.error).toBeFalsy();
|
||||
expect(result.current.data).toEqual(mockData);
|
||||
});
|
||||
|
||||
it('should handle the errors correctly', async () => {
|
||||
const mock = new MockAdapter(axios);
|
||||
|
||||
mock.onGet().replyOnce(() => {
|
||||
return new Promise((_, reject) => {
|
||||
reject(new Error(''));
|
||||
});
|
||||
});
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() => useFetch());
|
||||
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.isLoading).toBeFalsy();
|
||||
expect(result.current.error).toBeTruthy();
|
||||
expect(result.current.data).toBeNull();
|
||||
});
|
||||
});
|
@ -32,7 +32,7 @@ const Plugins = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const { status, data } = useQuery('list-plugins', () => fetchPlugins(notifyLoad), {
|
||||
const { status, data } = useQuery('list-installed-plugins', () => fetchPlugins(notifyLoad), {
|
||||
onError: () => {
|
||||
toggleNotification({
|
||||
type: 'warning',
|
||||
|
@ -1,28 +0,0 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
// TODO : To migrate with @strapi/design-system
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 2rem;
|
||||
border-radius: 4px;
|
||||
border-left: 4px solid ${({ theme }) => theme.main.colors.mediumBlue};
|
||||
box-shadow: 0 2px 4px ${({ theme }) => theme.main.colors.darkGrey};
|
||||
padding: 8px 16px;
|
||||
|
||||
.bannerImage {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.bannerLink {
|
||||
color: ${({ theme }) => theme.main.colors.mediumBlue};
|
||||
font-weight: ${({ theme }) => theme.main.fontWeights.bold};
|
||||
svg {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
@ -1,37 +0,0 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useTracking } from '@strapi/helper-plugin';
|
||||
import Wrapper from './Wrapper';
|
||||
import LogoStrapi from '../../../assets/images/banner_strapi-rocket.png';
|
||||
|
||||
const MarketplaceBanner = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { trackUsage } = useTracking();
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<img
|
||||
className="bannerImage"
|
||||
src={LogoStrapi}
|
||||
alt={formatMessage({ id: 'app.components.MarketplaceBanner.image.alt' })}
|
||||
/>
|
||||
<div>
|
||||
<div>
|
||||
<FormattedMessage id="app.components.MarketplaceBanner" />
|
||||
</div>
|
||||
<a
|
||||
href="https://github.com/strapi/awesome-strapi"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="bannerLink"
|
||||
onClick={() => trackUsage('didGoToStrapiAwesome')}
|
||||
>
|
||||
<FormattedMessage id="app.components.MarketplaceBanner.link" />
|
||||
<i className="fa fa-external-link-alt" />
|
||||
</a>
|
||||
</div>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default MarketplaceBanner;
|
@ -1,148 +0,0 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
.wrapper {
|
||||
position: relative;
|
||||
min-height: 216px;
|
||||
margin-bottom: 3.6rem;
|
||||
padding: 1.2rem 1.5rem;
|
||||
padding-bottom: 0;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 4px #e3e9f3;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
display: flex;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
|
||||
> div:first-child {
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
> div:last-child {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
i,
|
||||
svg {
|
||||
margin-left: 7px;
|
||||
color: #b3b5b9;
|
||||
font-size: 1rem;
|
||||
vertical-align: baseline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.cardDescription {
|
||||
height: 54px;
|
||||
margin-top: 27px;
|
||||
margin-bottom: 9px;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
|
||||
> span:last-child {
|
||||
color: #1c5de7;
|
||||
}
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.cardFooter {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
padding: 0.9rem 1.5rem 1rem;
|
||||
background-color: #fafafb;
|
||||
justify-content: space-between;
|
||||
flex-direction: row-reverse;
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
.compatible {
|
||||
margin-top: 3px;
|
||||
color: #5a9e06;
|
||||
font-size: 1.3rem;
|
||||
font-style: italic;
|
||||
|
||||
> i,
|
||||
> svg {
|
||||
margin-right: 7px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.settings {
|
||||
margin-top: 3px;
|
||||
color: #323740;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
|
||||
> i,
|
||||
> svg {
|
||||
margin-right: 7px;
|
||||
font-size: 11px;
|
||||
vertical-align: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
height: 26px;
|
||||
min-width: 89px !important;
|
||||
padding: 0 15px;
|
||||
margin: 0;
|
||||
border-radius: 2px !important;
|
||||
line-height: 23px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.frame {
|
||||
width: 70px;
|
||||
height: 36px;
|
||||
margin: auto 0;
|
||||
text-align: center;
|
||||
border: 1px solid #f3f3f7;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
> img {
|
||||
max-height: 36px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.helper {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.primary {
|
||||
background: linear-gradient(315deg, #0097f6 0%, #005eea 100%);
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
||||
&:active {
|
||||
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
.secondary {
|
||||
border: 1px solid #dfe0e1;
|
||||
font-weight: 600;
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
@ -1,185 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* PluginCard
|
||||
*
|
||||
*/
|
||||
/* eslint-disable */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { Button, PopUpWarning, CheckPermissions } from '@strapi/helper-plugin';
|
||||
import adminPermissions from '../../../permissions';
|
||||
import Wrapper from './Wrapper';
|
||||
|
||||
/* eslint-disable react/no-unused-state */
|
||||
class PluginCard extends React.Component {
|
||||
state = {
|
||||
boostrapCol: 'col-lg-4',
|
||||
showModalAutoReload: false,
|
||||
showModalEnv: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
// Listen window resize.
|
||||
window.addEventListener('resize', this.setBoostrapCol);
|
||||
this.setBoostrapCol();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.setBoostrapCol);
|
||||
}
|
||||
|
||||
setBoostrapCol = () => {
|
||||
let boostrapCol = 'col-lg-4';
|
||||
|
||||
if (window.innerWidth > 1680) {
|
||||
boostrapCol = 'col-lg-3';
|
||||
}
|
||||
|
||||
if (window.innerWidth > 2300) {
|
||||
boostrapCol = 'col-lg-2';
|
||||
}
|
||||
|
||||
this.setState({ boostrapCol });
|
||||
};
|
||||
|
||||
handleDownloadPlugin = e => {
|
||||
const {
|
||||
autoReload,
|
||||
currentEnvironment,
|
||||
downloadPlugin,
|
||||
history: { push },
|
||||
isAlreadyInstalled,
|
||||
plugin: { id },
|
||||
} = this.props;
|
||||
|
||||
if (!autoReload) {
|
||||
this.setState({ showModalAutoReload: true });
|
||||
} else if (currentEnvironment !== 'development') {
|
||||
this.setState({ showModalEnv: true });
|
||||
} else if (!isAlreadyInstalled) {
|
||||
downloadPlugin(id);
|
||||
} else {
|
||||
push('/list-plugins');
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const buttonClass = !this.props.isAlreadyInstalled ? 'primary' : 'secondary';
|
||||
const buttonLabel = this.props.isAlreadyInstalled
|
||||
? 'app.components.PluginCard.Button.label.install'
|
||||
: 'app.components.PluginCard.Button.label.download';
|
||||
|
||||
const settingsComponent = null;
|
||||
|
||||
const descriptions = {
|
||||
short:
|
||||
this.props.plugin.id === 'support-us' ? (
|
||||
<FormattedMessage id={this.props.plugin.description.short} />
|
||||
) : (
|
||||
this.props.plugin.description.short
|
||||
),
|
||||
long:
|
||||
this.props.plugin.id === 'support-us' ? (
|
||||
<FormattedMessage
|
||||
id={this.props.plugin.description.long || this.props.plugin.description.short}
|
||||
/>
|
||||
) : (
|
||||
this.props.plugin.description.long || this.props.plugin.description.short
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper className={this.state.boostrapCol}>
|
||||
<div className="wrapper">
|
||||
<div className="cardTitle">
|
||||
<div className="frame">
|
||||
<span className="helper" />
|
||||
<img src={this.props.plugin.logo} alt="icon" />
|
||||
</div>
|
||||
<div
|
||||
onClick={e => {
|
||||
// FIXME: dead link as we are changing the naming. Would be better to use a url comming from the api call directly
|
||||
window.open(
|
||||
`https://github.com/strapi/strapi/tree/master/packages/strapi-plugin-${this.props.plugin.id}`,
|
||||
'_blank'
|
||||
);
|
||||
}}
|
||||
>
|
||||
{this.props.plugin.name} <i className="fa fa-external-link-alt" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="cardDescription">{descriptions.long}</div>
|
||||
<div className="cardFooter" onClick={e => e.stopPropagation()}>
|
||||
<div className="cardFooterButton">
|
||||
<CheckPermissions permissions={adminPermissions.marketplace.install}>
|
||||
<Button
|
||||
className={`${buttonClass} button`}
|
||||
label={buttonLabel}
|
||||
type="button"
|
||||
onClick={this.handleDownloadPlugin}
|
||||
/>
|
||||
</CheckPermissions>
|
||||
</div>
|
||||
{this.props.isAlreadyInstalled ? (
|
||||
settingsComponent
|
||||
) : (
|
||||
<div className="compatible">
|
||||
<i className={`fa fa-${this.props.plugin.isCompatible ? 'check' : 'times'}`} />
|
||||
<FormattedMessage
|
||||
id={`app.components.PluginCard.compatible${
|
||||
this.props.plugin.id === 'support-us' ? 'Community' : ''
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PopUpWarning
|
||||
content={{
|
||||
message: 'app.components.PluginCard.PopUpWarning.install.impossible.autoReload.needed',
|
||||
title: 'app.components.PluginCard.PopUpWarning.install.impossible.title',
|
||||
confirm: 'app.components.PluginCard.PopUpWarning.install.impossible.confirm',
|
||||
}}
|
||||
isOpen={this.state.showModalAutoReload}
|
||||
onlyConfirmButton
|
||||
onConfirm={() => this.setState({ showModalAutoReload: false })}
|
||||
popUpWarningType="warning"
|
||||
/>
|
||||
<PopUpWarning
|
||||
content={{
|
||||
message: 'app.components.PluginCard.PopUpWarning.install.impossible.environment',
|
||||
title: 'app.components.PluginCard.PopUpWarning.install.impossible.title',
|
||||
confirm: 'app.components.PluginCard.PopUpWarning.install.impossible.confirm',
|
||||
}}
|
||||
isOpen={this.state.showModalEnv}
|
||||
onlyConfirmButton
|
||||
onConfirm={() => this.setState({ showModalEnv: false })}
|
||||
popUpWarningType="warning"
|
||||
/>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PluginCard.defaultProps = {
|
||||
isAlreadyInstalled: false,
|
||||
plugin: {
|
||||
description: '',
|
||||
id: '',
|
||||
name: '',
|
||||
price: 0,
|
||||
ratings: 5,
|
||||
},
|
||||
};
|
||||
|
||||
PluginCard.propTypes = {
|
||||
currentEnvironment: PropTypes.string.isRequired,
|
||||
downloadPlugin: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired,
|
||||
isAlreadyInstalled: PropTypes.bool,
|
||||
plugin: PropTypes.object,
|
||||
};
|
||||
|
||||
export default PluginCard;
|
@ -1,5 +0,0 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div``;
|
||||
|
||||
export default Wrapper;
|
Binary file not shown.
Before Width: | Height: | Size: 126 KiB |
@ -0,0 +1,111 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import styled from 'styled-components';
|
||||
import { Box } from '@strapi/design-system/Box';
|
||||
import { Stack } from '@strapi/design-system/Stack';
|
||||
import { Typography } from '@strapi/design-system/Typography';
|
||||
import { Button } from '@strapi/design-system/Button';
|
||||
import { LinkButton } from '@strapi/design-system/LinkButton';
|
||||
import { Flex } from '@strapi/design-system/Flex';
|
||||
import ExternalLink from '@strapi/icons/ExternalLink';
|
||||
import Duplicate from '@strapi/icons/Duplicate';
|
||||
|
||||
// Custom component to have an ellipsis after the 2nd line
|
||||
const EllipsisText = styled(Typography)`
|
||||
/* stylelint-disable value-no-vendor-prefix, property-no-vendor-prefix */
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
/* stylelint-enable value-no-vendor-prefix, property-no-vendor-prefix */
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const PluginCard = ({ plugin }) => {
|
||||
const { attributes } = plugin;
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
return (
|
||||
<Flex
|
||||
direction="column"
|
||||
justifyContent="space-between"
|
||||
paddingTop={4}
|
||||
paddingRight={6}
|
||||
paddingBottom={4}
|
||||
paddingLeft={6}
|
||||
hasRadius
|
||||
background="neutral0"
|
||||
shadow="tableShadow"
|
||||
height="100%"
|
||||
alignItems="normal"
|
||||
>
|
||||
<Box>
|
||||
<Box
|
||||
as="img"
|
||||
src={attributes.logo.url}
|
||||
alt={`${attributes.name} logo`}
|
||||
hasRadius
|
||||
width={11}
|
||||
height={11}
|
||||
/>
|
||||
<Box paddingTop={5}>
|
||||
<Typography as="h3" variant="delta">
|
||||
{attributes.name}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box paddingTop={2}>
|
||||
<EllipsisText as="p" variant="omega" textColor="neutral600">
|
||||
{attributes.description}
|
||||
</EllipsisText>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Stack horizontal size={2} style={{ alignSelf: 'flex-end' }} paddingTop={3}>
|
||||
<LinkButton
|
||||
size="S"
|
||||
href={`https://market.strapi.io/plugins/${attributes.slug}`}
|
||||
endIcon={<ExternalLink />}
|
||||
aria-label={formatMessage(
|
||||
{
|
||||
id: 'admin.pages.MarketPlacePage.plugin.info.label',
|
||||
defaultMessage: 'Learn more about {pluginName}',
|
||||
},
|
||||
{ pluginName: attributes.name }
|
||||
)}
|
||||
variant="tertiary"
|
||||
>
|
||||
{formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.plugin.info.text',
|
||||
defaultMessage: 'Learn more',
|
||||
})}
|
||||
</LinkButton>
|
||||
<Button size="S" endIcon={<Duplicate />} variant="secondary">
|
||||
{formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.plugin.copy',
|
||||
defaultMessage: 'Copy install command',
|
||||
})}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
PluginCard.propTypes = {
|
||||
plugin: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
attributes: PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
slug: PropTypes.string.isRequired,
|
||||
npmPackageName: PropTypes.string.isRequired,
|
||||
npmPackageUrl: PropTypes.string.isRequired,
|
||||
repositoryUrl: PropTypes.string.isRequired,
|
||||
logo: PropTypes.object.isRequired,
|
||||
developerName: PropTypes.string.isRequired,
|
||||
validated: PropTypes.bool.isRequired,
|
||||
strapiCompatibility: PropTypes.oneOf(['v3', 'v4']).isRequired,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default PluginCard;
|
@ -1,38 +1,21 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useQuery } from 'react-query';
|
||||
import styled from 'styled-components';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import {
|
||||
pxToRem,
|
||||
CheckPagePermissions,
|
||||
useFocusWhenNavigate,
|
||||
useTracking,
|
||||
LoadingIndicatorPage,
|
||||
useNotification,
|
||||
} from '@strapi/helper-plugin';
|
||||
import { useNotifyAT } from '@strapi/design-system/LiveRegions';
|
||||
import { Grid, GridItem } from '@strapi/design-system/Grid';
|
||||
import { Layout, HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
|
||||
import { Flex } from '@strapi/design-system/Flex';
|
||||
import { Box } from '@strapi/design-system/Box';
|
||||
import { Stack } from '@strapi/design-system/Stack';
|
||||
import { LinkButton } from '@strapi/design-system/LinkButton';
|
||||
import { Main } from '@strapi/design-system/Main';
|
||||
import { Typography } from '@strapi/design-system/Typography';
|
||||
import { fetchPlugins } from './utils/api';
|
||||
import adminPermissions from '../../permissions';
|
||||
import MarketplacePicture from './assets/marketplace-coming-soon.png';
|
||||
|
||||
const CenterTypography = styled(Typography)`
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
const Img = styled.img`
|
||||
width: ${190 / 16}rem;
|
||||
`;
|
||||
|
||||
const StackCentered = styled(Stack)`
|
||||
align-items: center;
|
||||
`;
|
||||
import PluginCard from './components/PluginCard';
|
||||
|
||||
const MarketPlacePage = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
@ -40,6 +23,8 @@ const MarketPlacePage = () => {
|
||||
const toggleNotification = useNotification();
|
||||
const { notifyStatus } = useNotifyAT();
|
||||
|
||||
useFocusWhenNavigate();
|
||||
|
||||
const title = formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.title',
|
||||
defaultMessage: 'Marketplace',
|
||||
@ -57,14 +42,18 @@ const MarketPlacePage = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const { status, data } = useQuery('list-plugins', () => fetchPlugins(notifyLoad), {
|
||||
onError: () => {
|
||||
toggleNotification({
|
||||
type: 'warning',
|
||||
message: { id: 'notification.error', defaultMessage: 'An error occured' },
|
||||
});
|
||||
},
|
||||
});
|
||||
const { status, data: pluginsResponse } = useQuery(
|
||||
'list-marketplace-plugins',
|
||||
() => fetchPlugins(notifyLoad),
|
||||
{
|
||||
onError: () => {
|
||||
toggleNotification({
|
||||
type: 'warning',
|
||||
message: { id: 'notification.error', defaultMessage: 'An error occured' },
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const isLoading = status !== 'success' && status !== 'error';
|
||||
|
||||
@ -82,89 +71,44 @@ const MarketPlacePage = () => {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Remove when using data, logging for now to avoid lint error
|
||||
console.log('plugins', data);
|
||||
|
||||
return (
|
||||
<CheckPagePermissions permissions={adminPermissions.marketplace.main}>
|
||||
<Layout>
|
||||
<Main>
|
||||
<Helmet
|
||||
title={formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.helmet',
|
||||
defaultMessage: 'Marketplace - Plugins',
|
||||
})}
|
||||
/>
|
||||
<HeaderLayout
|
||||
title={formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.title',
|
||||
defaultMessage: 'Marketplace',
|
||||
})}
|
||||
subtitle={formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.subtitle',
|
||||
defaultMessage: 'Get more out of Strapi',
|
||||
})}
|
||||
/>
|
||||
<ContentLayout>
|
||||
<StackCentered
|
||||
size={0}
|
||||
hasRadius
|
||||
background="neutral0"
|
||||
shadow="tableShadow"
|
||||
paddingTop={10}
|
||||
paddingBottom={10}
|
||||
>
|
||||
<Box paddingBottom={7}>
|
||||
<Img
|
||||
alt={formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.illustration',
|
||||
defaultMessage: 'marketplace illustration',
|
||||
})}
|
||||
src={MarketplacePicture}
|
||||
/>
|
||||
</Box>
|
||||
<Typography variant="alpha">
|
||||
{formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.coming-soon.1',
|
||||
defaultMessage: 'A new way to make Strapi awesome.',
|
||||
})}
|
||||
</Typography>
|
||||
<Typography variant="alpha" textColor="primary700">
|
||||
{formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.coming-soon.2',
|
||||
defaultMessage: 'A new way to make Strapi awesome.',
|
||||
})}
|
||||
</Typography>
|
||||
<Flex maxWidth={pxToRem(580)} paddingTop={3}>
|
||||
<CenterTypography variant="epsilon" textColor="neutral600">
|
||||
{formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.content.subtitle',
|
||||
defaultMessage:
|
||||
'The new marketplace will help you get more out of Strapi. We are working hard to offer the best experience to discover and install plugins.',
|
||||
})}
|
||||
</CenterTypography>
|
||||
</Flex>
|
||||
<Stack paddingTop={6} horizontal size={2}>
|
||||
{/* Temporarily hidden until we have the right URL for the link */}
|
||||
{/* <LinkButton href="https://strapi.io/" size="L" variant="secondary">
|
||||
{formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.submit.plugin.link',
|
||||
defaultMessage: 'Submit your plugin',
|
||||
})}
|
||||
</LinkButton> */}
|
||||
<LinkButton href="https://strapi.io/blog/strapi-market-is-coming-soon" size="L">
|
||||
{formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.blog.link',
|
||||
defaultMessage: 'Read our blog post',
|
||||
})}
|
||||
</LinkButton>
|
||||
</Stack>
|
||||
</StackCentered>
|
||||
</ContentLayout>
|
||||
</Main>
|
||||
</Layout>
|
||||
</CheckPagePermissions>
|
||||
<Layout>
|
||||
<Main>
|
||||
<Helmet
|
||||
title={formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.helmet',
|
||||
defaultMessage: 'Marketplace - Plugins',
|
||||
})}
|
||||
/>
|
||||
<HeaderLayout
|
||||
title={formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.title',
|
||||
defaultMessage: 'Marketplace',
|
||||
})}
|
||||
subtitle={formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.subtitle',
|
||||
defaultMessage: 'Get more out of Strapi',
|
||||
})}
|
||||
/>
|
||||
<ContentLayout>
|
||||
<Grid gap={4}>
|
||||
{pluginsResponse.data.map(plugin => (
|
||||
<GridItem col={4} s={6} xs={12} style={{ height: '100%' }} key={plugin.id}>
|
||||
<PluginCard plugin={plugin} />
|
||||
</GridItem>
|
||||
))}
|
||||
</Grid>
|
||||
</ContentLayout>
|
||||
</Main>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
export default MarketPlacePage;
|
||||
const ProtectedMarketPlace = () => (
|
||||
<CheckPagePermissions permissions={adminPermissions.marketplace.main}>
|
||||
<MarketPlacePage />
|
||||
</CheckPagePermissions>
|
||||
);
|
||||
|
||||
export { MarketPlacePage };
|
||||
export default ProtectedMarketPlace;
|
||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,550 @@
|
||||
import { setupServer } from 'msw/node';
|
||||
import { rest } from 'msw';
|
||||
|
||||
const handlers = [
|
||||
rest.get('*/plugins', (req, res, ctx) => {
|
||||
return res(
|
||||
ctx.delay(100),
|
||||
ctx.status(200),
|
||||
ctx.json({
|
||||
data: [
|
||||
{
|
||||
id: 'recQHmaveQknjaIdv',
|
||||
attributes: {
|
||||
name: 'Cloudflare pages',
|
||||
description:
|
||||
'This plugin lets you easily trigger Cloudflare Pages builds from Strapi.',
|
||||
slug: 'strapi-plugin-cloudflare-pages',
|
||||
npmPackageName: 'strapi-plugin-cloudflare-pages',
|
||||
npmPackageUrl: 'https://www.npmjs.com/package/strapi-plugin-cloudflare-pages',
|
||||
repositoryUrl: 'https://github.com/sarhugo/strapi-plugin-cloudflare-pages',
|
||||
logo: {
|
||||
id: 'attzLRKpax5MIrMtq',
|
||||
width: 160,
|
||||
height: 160,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/3e586bbcdd7dc2effc3770fd49506aa6/ddbb2540/cf-logo-v-rgb.jpg',
|
||||
filename: 'cf-logo-v-rgb.jpg',
|
||||
size: 25615,
|
||||
type: 'image/jpeg',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/aa98b52525fdeb5767cf554563a9df14/7a03d156',
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/a0e91d3564a0f41d89799e352b06c8ee/3d45329e',
|
||||
width: 160,
|
||||
height: 160,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/20b4afecf2bf8bc081c54eae92a7f599/d1e10f39',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
developerName: 'Hugo Sarti',
|
||||
validated: false,
|
||||
strapiCompatibility: 'v3',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'recWQXzTM5e6Friiq',
|
||||
attributes: {
|
||||
name: 'Comments',
|
||||
description: 'Powerful Strapi based comments moderation tool for you and your users',
|
||||
slug: 'strapi-plugin-comments',
|
||||
npmPackageName: 'strapi-plugin-comments',
|
||||
npmPackageUrl: 'https://www.npmjs.com/package/strapi-plugin-comments',
|
||||
repositoryUrl: 'https://github.com/VirtusLab-Open-Source/strapi-plugin-comments',
|
||||
logo: {
|
||||
id: 'att1xGwmQzDOC2UwY',
|
||||
width: 1080,
|
||||
height: 1080,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/eb4cd59876565af77c9c3e5966b59f10/2111bfc8/vl_strapi-comments.png',
|
||||
filename: 'vl_strapi-comments.png',
|
||||
size: 344804,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/92ec34110ff65c0993eac95a4f9ee906/76443a36',
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/5136e180187206b2a90bfa9a5ca65149/64187ef0',
|
||||
width: 512,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/4c3fdf040d05779adf251a737adcae55/590ff600',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
screenshots: [
|
||||
{
|
||||
id: 'att4y0AbotGdAOdEJ',
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/f6316615095b33ce67700a3810c1869c/a13c0ef1/screens.png',
|
||||
filename: 'screens.png',
|
||||
size: 625578,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/2ff8cdfc0f4c215ae63e96f21281b93d/d817fa87',
|
||||
width: 64,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/4ecf8b86b1af9061bcdf90f42253531b/1a88263e',
|
||||
width: 910,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/1f51a4dca550912863c9d43a8052ab77/e4fa5ec5',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'att3k9vSnVo0KFSEA',
|
||||
width: 2880,
|
||||
height: 1578,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/a3c3451815e017baa04f4b92f26c29ef/243d8656/Screenshot2022-01-27at07.48.19.png',
|
||||
filename: 'Screenshot 2022-01-27 at 07.48.19.png',
|
||||
size: 1545826,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/51d91e1e39eacf40f05fa193d367a306/1dbd8409',
|
||||
width: 66,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/392a6d72b82000b0b84d58c40319d3a0/2ccc6e5b',
|
||||
width: 934,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/45fc5b9d4bc83d2ef5e0aa36d2918b8d/a05010ef',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'attKuQmvrbDnp1tm1',
|
||||
width: 2880,
|
||||
height: 1582,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/d75abd544b3710060288547049d7bf22/1412b396/Screenshot2022-01-27at07.48.37.png',
|
||||
filename: 'Screenshot 2022-01-27 at 07.48.37.png',
|
||||
size: 1282068,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/c41517eac949e0da38f0f19344fe875b/cec423d6',
|
||||
width: 66,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/e7881ee4b0b75fc0f2d40c53efa94b01/6513dcc2',
|
||||
width: 932,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/60d7b535cc8b579ee09a64ce23ec607e/954df7b1',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'att3iUd2fPh6xgsU4',
|
||||
width: 2880,
|
||||
height: 1580,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/87efb22ce60c67971a16bac929bb24aa/ef2da9b7/Screenshot2022-01-27at07.48.47.png',
|
||||
filename: 'Screenshot 2022-01-27 at 07.48.47.png',
|
||||
size: 1386662,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/8e7ddb79f9ff320235a029df98872d74/85632ae0',
|
||||
width: 66,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/6d6ad9667c04b08709dc3e6f2f68f064/da46238e',
|
||||
width: 933,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/ebd28cadcab85bd217b066eeeb113723/6267c7e1',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'attSRD1UvyPislYg4',
|
||||
width: 2880,
|
||||
height: 1580,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/3b104067762dedac336a938f57676f93/4deb3bae/Screenshot2022-01-27at07.48.07.png',
|
||||
filename: 'Screenshot 2022-01-27 at 07.48.07.png',
|
||||
size: 1282540,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/c215d62e79d7d13d2c40016f3118a979/37e7af8e',
|
||||
width: 66,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/4895150e0da9ba7edfa32cf2348d79cb/f5e8af82',
|
||||
width: 933,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/8e7a00bd492421447458cd2ee739aba2/bc5f3759',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
developerName: 'Mateusz Ziarko',
|
||||
validated: false,
|
||||
strapiCompatibility: 'v4',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'rec0KouDUCBhydNW6',
|
||||
attributes: {
|
||||
name: 'Config Sync',
|
||||
description:
|
||||
'Migrate your config data across environments using the CLI or Strapi admin panel.',
|
||||
slug: 'strapi-plugin-config-sync',
|
||||
npmPackageName: 'strapi-plugin-config-sync',
|
||||
npmPackageUrl: 'https://www.npmjs.com/package/strapi-plugin-config-sync',
|
||||
repositoryUrl: 'https://github.com/boazpoolman/strapi-plugin-config-sync',
|
||||
logo: {
|
||||
id: 'att6OefK4471IpCZ5',
|
||||
width: 320,
|
||||
height: 320,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/e23a7231d12cce89cb4b05cbfe759d45/96f5f496/Screenshot2021-12-09at22.15.37.png',
|
||||
filename: 'Screenshot 2021-12-09 at 22.15.37.png',
|
||||
size: 11580,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/2f69cd2d5a884ad733c2e18bbe3d2e39/9cf40c6f',
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/8301d585b4aaa2977fa1e007feb02a17/1d121e13',
|
||||
width: 320,
|
||||
height: 320,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/15d442f81a47ff6ff002fd25ce6788d6/395c8aea',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
screenshots: [
|
||||
{
|
||||
id: 'att0QiAtNRfoz3mwF',
|
||||
width: 2206,
|
||||
height: 1284,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/b6afdee7abfbf5c63ef3d2de243f99a4/a5f3f48c/config-diff.png',
|
||||
filename: 'config-diff.png',
|
||||
size: 332901,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/2135d552f535ead55971c9ae016bb178/5b71c76e',
|
||||
width: 62,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/4b972ba187e2bd589c10987871ef00df/35f22c62',
|
||||
width: 880,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/3b88bba22b7d9d9ec456bf849efeac53/423f1a93',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
developerName: 'Boaz Poolman',
|
||||
validated: true,
|
||||
strapiCompatibility: 'v4',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'rec0Z7KLBCtaD6rC3',
|
||||
attributes: {
|
||||
name: 'Content Versioning',
|
||||
description:
|
||||
'This plugin enables you to versioning Content Types. It allows multiple draft versions✅ Keeps history of all changes (with time travel) ✅ ',
|
||||
slug: '@notum-cz-strapi-plugin-content-versioning',
|
||||
npmPackageName: '@notum-cz/strapi-plugin-content-versioning',
|
||||
npmPackageUrl:
|
||||
'https://www.npmjs.com/package/@notum-cz/strapi-plugin-content-versioning',
|
||||
repositoryUrl: 'https://github.com/notum-cz/strapi-plugin-content-versioning',
|
||||
logo: {
|
||||
id: 'attaMdJdER0feFBuX',
|
||||
width: 1280,
|
||||
height: 1280,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/0b86f18e2606ed7f53bd54d536a1bea5/13a87f30/Artboard7copy.png',
|
||||
filename: 'Artboard 7 copy.png',
|
||||
size: 35705,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/4c0179127f923c0ce01866c92e9664a8/347fbe74',
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/0edca5708e30dc9fce6c962dcc28dbce/39b83021',
|
||||
width: 512,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/a44ea395865d5f6ba71dbcae814cfc83/31c3fffc',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
screenshots: [
|
||||
{
|
||||
id: 'attGD52ggRIgnsUKp',
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/50126ddff8ef4ed7b7a693ecd156ae60/b6a9a4a6/Novprojekt15.png',
|
||||
filename: 'Nový projekt (15).png',
|
||||
size: 52163,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/60382a6542a77f90594526b68fe5182c/f54e7675',
|
||||
width: 64,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/05deee4e93b9b57e9cd4465e2c6622f1/1b377c4a',
|
||||
width: 910,
|
||||
height: 512,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/87ef842cda9b0647e7dd4d2f8a086379/303ecd98',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
developerName: 'Ondřej Janošík',
|
||||
validated: false,
|
||||
strapiCompatibility: 'v4',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'recwrVXGrUoOHdSlO',
|
||||
attributes: {
|
||||
name: 'Documentation',
|
||||
description: 'Create an OpenAPI Document and visualize your API with SWAGGER UI',
|
||||
slug: '@strapi-plugin-documentation',
|
||||
npmPackageName: '@strapi/plugin-documentation',
|
||||
npmPackageUrl: 'https://www.npmjs.com/package/@strapi/plugin-documentation',
|
||||
repositoryUrl:
|
||||
'https://github.com/strapi/strapi/tree/master/packages/plugins/documentation',
|
||||
logo: {
|
||||
id: 'att22dETRlzkfVWAl',
|
||||
width: 225,
|
||||
height: 225,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/b6998ac52e8b0460b8a14ced8074b788/2a4d4a90/swagger.png',
|
||||
filename: 'swagger.png',
|
||||
size: 6052,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/71a6b03e03a6b26647991a617478cdfa/8e1d8d2b',
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/c249c4953d5bb0e2f58ed7174afecc2f/796dca09',
|
||||
width: 225,
|
||||
height: 225,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/4b7bc3a765f3927b9fcd12809ddf82a8/d3a4b97b',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
developerName: 'Strapi team',
|
||||
validated: true,
|
||||
strapiCompatibility: 'v4',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'recqR0rWAw5gZHc1c',
|
||||
attributes: {
|
||||
name: 'Documentation v3',
|
||||
description: 'Create an OpenAPI Document and visualize your API with SWAGGER UI',
|
||||
slug: 'strapi-plugin-documentation',
|
||||
npmPackageName: 'strapi-plugin-documentation',
|
||||
npmPackageUrl: 'https://www.npmjs.com/package/strapi-plugin-documentation',
|
||||
repositoryUrl:
|
||||
'https://github.com/strapi/strapi/tree/v3.6.9/packages/strapi-plugin-documentation',
|
||||
logo: {
|
||||
id: 'att22dETRlzkfVWAl',
|
||||
width: 225,
|
||||
height: 225,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/b6998ac52e8b0460b8a14ced8074b788/2a4d4a90/swagger.png',
|
||||
filename: 'swagger.png',
|
||||
size: 6052,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/71a6b03e03a6b26647991a617478cdfa/8e1d8d2b',
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/c249c4953d5bb0e2f58ed7174afecc2f/796dca09',
|
||||
width: 225,
|
||||
height: 225,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/4b7bc3a765f3927b9fcd12809ddf82a8/d3a4b97b',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
developerName: 'Strapi team',
|
||||
validated: true,
|
||||
strapiCompatibility: 'v3',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'rec5s49X99wA67Ubj',
|
||||
attributes: {
|
||||
name: 'Transformer',
|
||||
description:
|
||||
'A plugin for Strapi Headless CMS that provides the ability to transform the API response. ',
|
||||
slug: 'strapi-plugin-transformer',
|
||||
npmPackageName: 'strapi-plugin-transformer',
|
||||
npmPackageUrl: 'https://www.npmjs.com/package/strapi-plugin-transformer',
|
||||
repositoryUrl: 'https://github.com/ComfortablyCoding/strapi-plugin-transformer',
|
||||
logo: {
|
||||
id: 'attbggDs1BgpGByTz',
|
||||
width: 158,
|
||||
height: 158,
|
||||
url:
|
||||
'https://dl.airtable.com/.attachments/5ffd1782a2fabf423ccd6f56c562f31a/b8f8598f/transformer-logo.png',
|
||||
filename: 'transformer-logo.png',
|
||||
size: 5787,
|
||||
type: 'image/png',
|
||||
thumbnails: {
|
||||
small: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/53ee41b18d2f704257a483ea17de9020/07cabde5',
|
||||
width: 36,
|
||||
height: 36,
|
||||
},
|
||||
large: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/46185b0bddbd1684ac02d12d490a621b/37a04f6c',
|
||||
width: 158,
|
||||
height: 158,
|
||||
},
|
||||
full: {
|
||||
url:
|
||||
'https://dl.airtable.com/.attachmentThumbnails/1a6e9c656aacaca5536abbe2c2964d30/5e904c9c',
|
||||
width: 3000,
|
||||
height: 3000,
|
||||
},
|
||||
},
|
||||
},
|
||||
developerName: 'Daedalus',
|
||||
validated: false,
|
||||
strapiCompatibility: 'v4',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
}),
|
||||
];
|
||||
|
||||
const server = setupServer(...handlers);
|
||||
|
||||
export default server;
|
@ -1,11 +1,19 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const MARKETPLACE_API_URL = 'https://market-api.strapi.io';
|
||||
|
||||
const fetchPlugins = async notify => {
|
||||
const { data } = await axios.get(`${process.env.STRAPI_ADMIN_MARKETPLACE_API_URL}/plugins`);
|
||||
const { data: response } = await axios.get(`${MARKETPLACE_API_URL}/plugins`);
|
||||
|
||||
// Only keep v4 plugins
|
||||
const filteredResponse = {
|
||||
...response,
|
||||
data: response.data.filter(plugin => plugin.attributes.strapiCompatibility === 'v4'),
|
||||
};
|
||||
|
||||
notify();
|
||||
|
||||
return data;
|
||||
return filteredResponse;
|
||||
};
|
||||
|
||||
export { fetchPlugins };
|
||||
|
@ -59,14 +59,12 @@
|
||||
"Auth.privacy-policy-agreement.terms": "terms",
|
||||
"Auth.reset-password.title": "Reset password",
|
||||
"admin.pages.MarketPlacePage.helmet": "Marketplace - Plugins",
|
||||
"admin.pages.MarketPlacePage.illustration": "marketplace illustration",
|
||||
"admin.pages.MarketPlacePage.title": "Marketplace",
|
||||
"admin.pages.MarketPlacePage.subtitle": "Get more out of Strapi",
|
||||
"admin.pages.MarketPlacePage.coming-soon.1": "A new way to make Strapi awesome.",
|
||||
"admin.pages.MarketPlacePage.coming-soon.2": "Coming soon.",
|
||||
"admin.pages.MarketPlacePage.content.subtitle": "The new marketplace will help you get more out of Strapi. We are working hard to offer the best experience to discover and install plugins.",
|
||||
"admin.pages.MarketPlacePage.plugin.info.text": "Learn more",
|
||||
"admin.pages.MarketPlacePage.plugin.info.label": "Learn more about {pluginName}",
|
||||
"admin.pages.MarketPlacePage.plugin.copy": "Copy install command",
|
||||
"admin.pages.MarketPlacePage.submit.plugin.link": "Submit your plugin",
|
||||
"admin.pages.MarketPlacePage.blog.link": "Read our blog post",
|
||||
"Content Manager": "Content Manager",
|
||||
"Content Type Builder": "Content-Types Builder",
|
||||
"Documentation": "Documentation",
|
||||
|
@ -25,8 +25,6 @@ const getClientEnvironment = options => {
|
||||
ADMIN_PATH: options.adminPath,
|
||||
NODE_ENV: options.env || 'development',
|
||||
STRAPI_ADMIN_BACKEND_URL: options.backend,
|
||||
STRAPI_ADMIN_MARKETPLACE_API_URL:
|
||||
process.env.STRAPI_ADMIN_MARKETPLACE_API_URL || 'https://market-api.strapi.io',
|
||||
}
|
||||
);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user