mirror of
https://github.com/strapi/strapi.git
synced 2025-09-20 22:10:06 +00:00
Merge branch 'main' into fix/clean-test-warnings
This commit is contained in:
commit
1039e207c0
1
examples/getstarted/.gitignore
vendored
1
examples/getstarted/.gitignore
vendored
@ -110,6 +110,7 @@ testApp
|
||||
license.txt
|
||||
exports
|
||||
*.cache
|
||||
dist
|
||||
build
|
||||
documentation
|
||||
.strapi-updater.json
|
||||
|
1
examples/kitchensink-ts/.gitignore
vendored
1
examples/kitchensink-ts/.gitignore
vendored
@ -110,5 +110,6 @@ coverage
|
||||
license.txt
|
||||
exports
|
||||
*.cache
|
||||
dist
|
||||
build
|
||||
.strapi-updater.json
|
||||
|
1
examples/kitchensink/.gitignore
vendored
1
examples/kitchensink/.gitignore
vendored
@ -110,5 +110,6 @@ coverage
|
||||
license.txt
|
||||
exports
|
||||
*.cache
|
||||
dist
|
||||
build
|
||||
.strapi-updater.json
|
||||
|
@ -62,6 +62,15 @@ async function initProject(projectName, program) {
|
||||
await checkInstallPath(resolve(projectName));
|
||||
}
|
||||
|
||||
const programFlags = program.options
|
||||
.reduce((acc, { short, long }) => [...acc, short, long], [])
|
||||
.filter(Boolean);
|
||||
|
||||
if (program.template && programFlags.includes(program.template)) {
|
||||
console.error(`${program.template} is not a valid template`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const hasDatabaseOptions = databaseOptions.some((opt) => program[opt]);
|
||||
|
||||
if (program.quickstart && hasDatabaseOptions) {
|
||||
|
@ -110,5 +110,6 @@ coverage
|
||||
license.txt
|
||||
exports
|
||||
*.cache
|
||||
dist
|
||||
build
|
||||
.strapi-updater.json
|
||||
|
@ -0,0 +1,110 @@
|
||||
import React from 'react';
|
||||
import semver from 'semver';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Tooltip } from '@strapi/design-system/Tooltip';
|
||||
import { Button } from '@strapi/design-system/Button';
|
||||
import { Box } from '@strapi/design-system/Box';
|
||||
import Duplicate from '@strapi/icons/Duplicate';
|
||||
|
||||
const TooltipButton = ({ description, installMessage, disabled, handleCopy, pluginName }) => (
|
||||
<Tooltip data-testid={`tooltip-${pluginName}`} description={description}>
|
||||
<Box>
|
||||
<Button
|
||||
size="S"
|
||||
startIcon={<Duplicate />}
|
||||
variant="secondary"
|
||||
disabled={disabled}
|
||||
onClick={handleCopy}
|
||||
>
|
||||
{installMessage}
|
||||
</Button>
|
||||
</Box>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
const CardButton = ({ strapiPeerDepVersion, strapiAppVersion, handleCopy, pluginName }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const versionRange = semver.validRange(strapiPeerDepVersion);
|
||||
const isCompatible = semver.satisfies(strapiAppVersion, versionRange);
|
||||
|
||||
const installMessage = formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.plugin.copy',
|
||||
defaultMessage: 'Copy install command',
|
||||
});
|
||||
|
||||
// Only plugins receive a strapiAppVersion
|
||||
if (strapiAppVersion) {
|
||||
if (!versionRange) {
|
||||
return (
|
||||
<TooltipButton
|
||||
installMessage={installMessage}
|
||||
pluginName={pluginName}
|
||||
description={formatMessage(
|
||||
{
|
||||
id: 'admin.pages.MarketPlacePage.plugin.version.null',
|
||||
defaultMessage:
|
||||
'Unable to verify compatibility with your Strapi version: "{strapiAppVersion}"',
|
||||
},
|
||||
{ strapiAppVersion }
|
||||
)}
|
||||
handleCopy={handleCopy}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isCompatible) {
|
||||
return (
|
||||
<TooltipButton
|
||||
installMessage={installMessage}
|
||||
pluginName={pluginName}
|
||||
description={formatMessage(
|
||||
{
|
||||
id: 'admin.pages.MarketPlacePage.plugin.version',
|
||||
defaultMessage:
|
||||
'Update your Strapi version: "{strapiAppVersion}" to: "{versionRange}"',
|
||||
},
|
||||
{
|
||||
strapiAppVersion,
|
||||
versionRange,
|
||||
}
|
||||
)}
|
||||
disabled
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Button size="S" startIcon={<Duplicate />} variant="secondary" onClick={handleCopy}>
|
||||
{installMessage}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
TooltipButton.defaultProps = {
|
||||
disabled: false,
|
||||
handleCopy: null,
|
||||
};
|
||||
|
||||
TooltipButton.propTypes = {
|
||||
description: PropTypes.string.isRequired,
|
||||
installMessage: PropTypes.string.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
handleCopy: PropTypes.func,
|
||||
pluginName: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
CardButton.defaultProps = {
|
||||
strapiAppVersion: null,
|
||||
strapiPeerDepVersion: null,
|
||||
};
|
||||
|
||||
CardButton.propTypes = {
|
||||
strapiAppVersion: PropTypes.string,
|
||||
strapiPeerDepVersion: PropTypes.string,
|
||||
handleCopy: PropTypes.func.isRequired,
|
||||
pluginName: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default CardButton;
|
@ -1,20 +1,34 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
import { useNotification, useTracking } from '@strapi/helper-plugin';
|
||||
import { Box } from '@strapi/design-system/Box';
|
||||
import { Icon } from '@strapi/design-system/Icon';
|
||||
import { Typography } from '@strapi/design-system/Typography';
|
||||
import Check from '@strapi/icons/Check';
|
||||
import Duplicate from '@strapi/icons/Duplicate';
|
||||
import { Button } from '@strapi/design-system/Button';
|
||||
import CardButton from './CardButton';
|
||||
|
||||
const InstallPluginButton = ({ isInstalled, isInDevelopmentMode, commandToCopy }) => {
|
||||
const InstallPluginButton = ({
|
||||
isInstalled,
|
||||
isInDevelopmentMode,
|
||||
commandToCopy,
|
||||
strapiAppVersion,
|
||||
strapiPeerDepVersion,
|
||||
pluginName,
|
||||
}) => {
|
||||
const toggleNotification = useNotification();
|
||||
const { formatMessage } = useIntl();
|
||||
const { trackUsage } = useTracking();
|
||||
|
||||
const handleCopy = () => {
|
||||
navigator.clipboard.writeText(commandToCopy);
|
||||
trackUsage('willInstallPlugin');
|
||||
toggleNotification({
|
||||
type: 'success',
|
||||
message: { id: 'admin.pages.MarketPlacePage.plugin.copy.success' },
|
||||
});
|
||||
};
|
||||
|
||||
// Already installed
|
||||
if (isInstalled) {
|
||||
return (
|
||||
@ -33,23 +47,12 @@ const InstallPluginButton = ({ isInstalled, isInDevelopmentMode, commandToCopy }
|
||||
// In development, show install button
|
||||
if (isInDevelopmentMode) {
|
||||
return (
|
||||
<CopyToClipboard
|
||||
onCopy={() => {
|
||||
trackUsage('willInstallPlugin');
|
||||
toggleNotification({
|
||||
type: 'success',
|
||||
message: { id: 'admin.pages.MarketPlacePage.plugin.copy.success' },
|
||||
});
|
||||
}}
|
||||
text={commandToCopy}
|
||||
>
|
||||
<Button size="S" startIcon={<Duplicate />} variant="secondary">
|
||||
{formatMessage({
|
||||
id: 'admin.pages.MarketPlacePage.plugin.copy',
|
||||
defaultMessage: 'Copy install command',
|
||||
})}
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
<CardButton
|
||||
strapiAppVersion={strapiAppVersion}
|
||||
strapiPeerDepVersion={strapiPeerDepVersion}
|
||||
handleCopy={handleCopy}
|
||||
pluginName={pluginName}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -57,10 +60,18 @@ const InstallPluginButton = ({ isInstalled, isInDevelopmentMode, commandToCopy }
|
||||
return null;
|
||||
};
|
||||
|
||||
InstallPluginButton.defaultProps = {
|
||||
strapiAppVersion: null,
|
||||
strapiPeerDepVersion: null,
|
||||
};
|
||||
|
||||
InstallPluginButton.propTypes = {
|
||||
isInstalled: PropTypes.bool.isRequired,
|
||||
isInDevelopmentMode: PropTypes.bool.isRequired,
|
||||
commandToCopy: PropTypes.string.isRequired,
|
||||
strapiAppVersion: PropTypes.string,
|
||||
strapiPeerDepVersion: PropTypes.string,
|
||||
pluginName: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default InstallPluginButton;
|
||||
|
@ -32,6 +32,7 @@ const NpmPackageCard = ({
|
||||
useYarn,
|
||||
isInDevelopmentMode,
|
||||
npmPackageType,
|
||||
strapiAppVersion,
|
||||
}) => {
|
||||
const { attributes } = npmPackage;
|
||||
const { formatMessage } = useIntl();
|
||||
@ -139,6 +140,9 @@ const NpmPackageCard = ({
|
||||
isInstalled={isInstalled}
|
||||
isInDevelopmentMode={isInDevelopmentMode}
|
||||
commandToCopy={commandToCopy}
|
||||
strapiAppVersion={strapiAppVersion}
|
||||
strapiPeerDepVersion={attributes.strapiVersion}
|
||||
pluginName={attributes.name}
|
||||
/>
|
||||
</Stack>
|
||||
</Flex>
|
||||
@ -147,6 +151,7 @@ const NpmPackageCard = ({
|
||||
|
||||
NpmPackageCard.defaultProps = {
|
||||
isInDevelopmentMode: false,
|
||||
strapiAppVersion: null,
|
||||
};
|
||||
|
||||
NpmPackageCard.propTypes = {
|
||||
@ -164,12 +169,14 @@ NpmPackageCard.propTypes = {
|
||||
validated: PropTypes.bool.isRequired,
|
||||
madeByStrapi: PropTypes.bool.isRequired,
|
||||
strapiCompatibility: PropTypes.oneOf(['v3', 'v4']),
|
||||
strapiVersion: PropTypes.string,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
isInstalled: PropTypes.bool.isRequired,
|
||||
useYarn: PropTypes.bool.isRequired,
|
||||
isInDevelopmentMode: PropTypes.bool,
|
||||
npmPackageType: PropTypes.string.isRequired,
|
||||
strapiAppVersion: PropTypes.string,
|
||||
};
|
||||
|
||||
export default NpmPackageCard;
|
||||
|
@ -9,6 +9,7 @@ const NpmPackagesGrid = ({
|
||||
useYarn,
|
||||
isInDevelopmentMode,
|
||||
npmPackageType,
|
||||
strapiAppVersion,
|
||||
}) => {
|
||||
// Check if an individual package is in the dependencies
|
||||
const isAlreadyInstalled = useCallback(
|
||||
@ -26,6 +27,7 @@ const NpmPackagesGrid = ({
|
||||
useYarn={useYarn}
|
||||
isInDevelopmentMode={isInDevelopmentMode}
|
||||
npmPackageType={npmPackageType}
|
||||
strapiAppVersion={strapiAppVersion}
|
||||
/>
|
||||
</GridItem>
|
||||
))}
|
||||
@ -35,6 +37,7 @@ const NpmPackagesGrid = ({
|
||||
|
||||
NpmPackagesGrid.defaultProps = {
|
||||
installedPackageNames: [],
|
||||
strapiAppVersion: null,
|
||||
};
|
||||
|
||||
NpmPackagesGrid.propTypes = {
|
||||
@ -43,6 +46,7 @@ NpmPackagesGrid.propTypes = {
|
||||
useYarn: PropTypes.bool.isRequired,
|
||||
isInDevelopmentMode: PropTypes.bool.isRequired,
|
||||
npmPackageType: PropTypes.string.isRequired,
|
||||
strapiAppVersion: PropTypes.string,
|
||||
};
|
||||
|
||||
export default NpmPackagesGrid;
|
||||
|
@ -50,7 +50,7 @@ const MarketPlacePage = () => {
|
||||
const toggleNotification = useNotification();
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [npmPackageType, setNpmPackageType] = useState('plugin');
|
||||
const { autoReload: isInDevelopmentMode, dependencies, useYarn } = useAppInfos();
|
||||
const { autoReload: isInDevelopmentMode, dependencies, useYarn, strapiVersion } = useAppInfos();
|
||||
const isOnline = useNavigatorOnLine();
|
||||
|
||||
useFocusWhenNavigate();
|
||||
@ -247,6 +247,7 @@ const MarketPlacePage = () => {
|
||||
useYarn={useYarn}
|
||||
isInDevelopmentMode={isInDevelopmentMode}
|
||||
npmPackageType="plugin"
|
||||
strapiAppVersion={strapiVersion}
|
||||
/>
|
||||
)}
|
||||
</TabPanel>
|
||||
|
@ -1223,38 +1223,46 @@ exports[`Marketplace page renders and matches the plugin tab snapshot 1`] = `
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
class="c51 c52"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="c53 c54 c55"
|
||||
aria-describedby="tooltip-3"
|
||||
class=""
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
<button
|
||||
aria-disabled="false"
|
||||
class="c51 c52"
|
||||
type="button"
|
||||
>
|
||||
<path
|
||||
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
|
||||
fill="#212134"
|
||||
/>
|
||||
<path
|
||||
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
|
||||
fill="#212134"
|
||||
/>
|
||||
</svg>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="c53 c54 c55"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
|
||||
fill="#212134"
|
||||
/>
|
||||
<path
|
||||
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
|
||||
fill="#212134"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
class="c56 c57"
|
||||
>
|
||||
Copy install command
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<span
|
||||
class="c56 c57"
|
||||
>
|
||||
Copy install command
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1340,38 +1348,47 @@ exports[`Marketplace page renders and matches the plugin tab snapshot 1`] = `
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
class="c51 c52"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="c53 c54 c55"
|
||||
aria-describedby="tooltip-5"
|
||||
class=""
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
<button
|
||||
aria-disabled="true"
|
||||
class="c51 c52"
|
||||
disabled=""
|
||||
type="button"
|
||||
>
|
||||
<path
|
||||
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
|
||||
fill="#212134"
|
||||
/>
|
||||
<path
|
||||
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
|
||||
fill="#212134"
|
||||
/>
|
||||
</svg>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="c53 c54 c55"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
|
||||
fill="#212134"
|
||||
/>
|
||||
<path
|
||||
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
|
||||
fill="#212134"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
class="c56 c57"
|
||||
>
|
||||
Copy install command
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<span
|
||||
class="c56 c57"
|
||||
>
|
||||
Copy install command
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1410,7 +1427,7 @@ exports[`Marketplace page renders and matches the plugin tab snapshot 1`] = `
|
||||
Documentation
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-3"
|
||||
aria-describedby="tooltip-7"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -1579,38 +1596,47 @@ exports[`Marketplace page renders and matches the plugin tab snapshot 1`] = `
|
||||
</svg>
|
||||
</div>
|
||||
</a>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
class="c51 c52"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="c53 c54 c55"
|
||||
aria-describedby="tooltip-9"
|
||||
class=""
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
<button
|
||||
aria-disabled="true"
|
||||
class="c51 c52"
|
||||
disabled=""
|
||||
type="button"
|
||||
>
|
||||
<path
|
||||
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
|
||||
fill="#212134"
|
||||
/>
|
||||
<path
|
||||
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
|
||||
fill="#212134"
|
||||
/>
|
||||
</svg>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="c53 c54 c55"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
|
||||
fill="#212134"
|
||||
/>
|
||||
<path
|
||||
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
|
||||
fill="#212134"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<span
|
||||
class="c56 c57"
|
||||
>
|
||||
Copy install command
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<span
|
||||
class="c56 c57"
|
||||
>
|
||||
Copy install command
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -2724,7 +2750,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
Amazon Ses
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-9"
|
||||
aria-describedby="tooltip-21"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -2856,7 +2882,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
AWS S3
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-11"
|
||||
aria-describedby="tooltip-23"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -2988,7 +3014,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
Cloudinary
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-13"
|
||||
aria-describedby="tooltip-25"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -3110,7 +3136,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
Local Upload
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-15"
|
||||
aria-describedby="tooltip-27"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -3242,7 +3268,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
Mailgun
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-17"
|
||||
aria-describedby="tooltip-29"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -3374,7 +3400,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
Nodemailer
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-19"
|
||||
aria-describedby="tooltip-31"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -3506,7 +3532,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
Rackspace
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-21"
|
||||
aria-describedby="tooltip-33"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -3638,7 +3664,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
SendGrid
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-23"
|
||||
aria-describedby="tooltip-35"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -3770,7 +3796,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
|
||||
Sendmail
|
||||
<span>
|
||||
<div
|
||||
aria-describedby="tooltip-25"
|
||||
aria-describedby="tooltip-37"
|
||||
class="c43"
|
||||
tabindex="0"
|
||||
>
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
screen,
|
||||
getByText,
|
||||
queryByText,
|
||||
getByRole,
|
||||
} from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
@ -35,6 +36,7 @@ jest.mock('@strapi/helper-plugin', () => ({
|
||||
'@strapi/plugin-documentation': '4.2.0',
|
||||
'@strapi/provider-upload-cloudinary': '4.2.0',
|
||||
},
|
||||
strapiVersion: '4.1.0',
|
||||
useYarn: true,
|
||||
})),
|
||||
}));
|
||||
@ -215,7 +217,7 @@ describe('Marketplace page', () => {
|
||||
expect(pluginCardText).toEqual(null);
|
||||
});
|
||||
|
||||
it('shows the installed text for installed plugins', async () => {
|
||||
it('shows the installed text for installed plugins', () => {
|
||||
render(App);
|
||||
const pluginsTab = screen.getByRole('tab', { name: /plugins/i });
|
||||
fireEvent.click(pluginsTab);
|
||||
@ -235,7 +237,7 @@ describe('Marketplace page', () => {
|
||||
expect(notInstalledText).toBeVisible();
|
||||
});
|
||||
|
||||
it('shows the installed text for installed providers', async () => {
|
||||
it('shows the installed text for installed providers', () => {
|
||||
// Open providers tab
|
||||
render(App);
|
||||
const providersTab = screen.getByRole('tab', { name: /providers/i });
|
||||
@ -255,4 +257,38 @@ describe('Marketplace page', () => {
|
||||
const notInstalledText = queryByText(notInstalledCard, /copy install command/i);
|
||||
expect(notInstalledText).toBeVisible();
|
||||
});
|
||||
|
||||
it('disables the button and shows compatibility tooltip message when version provided', async () => {
|
||||
const { getByTestId } = render(App);
|
||||
const alreadyInstalledCard = screen
|
||||
.getAllByTestId('npm-package-card')
|
||||
.find((div) => div.innerHTML.includes('Transformer'));
|
||||
const button = getByRole(alreadyInstalledCard, 'button', { name: /copy install command/i });
|
||||
const tooltip = getByTestId(`tooltip-Transformer`);
|
||||
fireEvent.mouseOver(button);
|
||||
await waitFor(() => {
|
||||
expect(tooltip).toBeVisible();
|
||||
});
|
||||
expect(button).toBeDisabled();
|
||||
expect(tooltip).toBeInTheDocument();
|
||||
expect(tooltip).toHaveTextContent('Update your Strapi version: "4.1.0" to: "4.0.7"');
|
||||
});
|
||||
|
||||
it('shows compatibility tooltip message when no version provided', async () => {
|
||||
const { getByTestId } = render(App);
|
||||
const alreadyInstalledCard = screen
|
||||
.getAllByTestId('npm-package-card')
|
||||
.find((div) => div.innerHTML.includes('Config Sync'));
|
||||
const button = getByRole(alreadyInstalledCard, 'button', { name: /copy install command/i });
|
||||
const tooltip = getByTestId(`tooltip-Config Sync`);
|
||||
fireEvent.mouseOver(button);
|
||||
await waitFor(() => {
|
||||
expect(tooltip).toBeVisible();
|
||||
});
|
||||
expect(button).not.toBeDisabled();
|
||||
expect(tooltip).toBeInTheDocument();
|
||||
expect(tooltip).toHaveTextContent(
|
||||
'Unable to verify compatibility with your Strapi version: "4.1.0"'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -48,6 +48,7 @@ const handlers = [
|
||||
validated: false,
|
||||
madeByStrapi: false,
|
||||
strapiCompatibility: 'v3',
|
||||
strapiVersion: '^4.0.0',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -221,6 +222,7 @@ const handlers = [
|
||||
validated: false,
|
||||
madeByStrapi: false,
|
||||
strapiCompatibility: 'v4',
|
||||
strapiVersion: '4.x.x',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -291,6 +293,7 @@ const handlers = [
|
||||
validated: true,
|
||||
madeByStrapi: false,
|
||||
strapiCompatibility: 'v4',
|
||||
strapiVersion: 'Contact developer',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -362,6 +365,7 @@ const handlers = [
|
||||
validated: false,
|
||||
madeByStrapi: false,
|
||||
strapiCompatibility: 'v4',
|
||||
strapiVersion: '^3.4.2',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -404,6 +408,7 @@ const handlers = [
|
||||
validated: true,
|
||||
madeByStrapi: true,
|
||||
strapiCompatibility: 'v4',
|
||||
strapiVersion: '^4.0.7',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -446,6 +451,7 @@ const handlers = [
|
||||
validated: true,
|
||||
madeByStrapi: false,
|
||||
strapiCompatibility: 'v3',
|
||||
strapiVersion: '^4.3.0',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -488,6 +494,7 @@ const handlers = [
|
||||
validated: false,
|
||||
madeByStrapi: false,
|
||||
strapiCompatibility: 'v4',
|
||||
strapiVersion: '4.0.7',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -100,11 +100,11 @@
|
||||
"Settings.apiTokens.duration.30-days": "30 days",
|
||||
"Settings.apiTokens.duration.90-days": "90 days",
|
||||
"Settings.apiTokens.duration.unlimited": "Unlimited",
|
||||
"Settings.apiTokens.form.duration":"Token duration",
|
||||
"Settings.apiTokens.form.type":"Token type",
|
||||
"Settings.apiTokens.duration.expiration-date":"Expiration date",
|
||||
"Settings.apiTokens.createPage.permissions.title":"Permissions",
|
||||
"Settings.apiTokens.createPage.permissions.description":"Only actions bound by a route are listed below.",
|
||||
"Settings.apiTokens.form.duration": "Token duration",
|
||||
"Settings.apiTokens.form.type": "Token type",
|
||||
"Settings.apiTokens.duration.expiration-date": "Expiration date",
|
||||
"Settings.apiTokens.createPage.permissions.title": "Permissions",
|
||||
"Settings.apiTokens.createPage.permissions.description": "Only actions bound by a route are listed below.",
|
||||
"Settings.apiTokens.RegenerateDialog.title": "Regenerate token",
|
||||
"Settings.apiTokens.popUpWarning.message": "Are you sure you want to regenerate this token?",
|
||||
"Settings.apiTokens.Button.cancel": "Cancel",
|
||||
@ -270,6 +270,8 @@
|
||||
"admin.pages.MarketPlacePage.plugin.installed": "Installed",
|
||||
"admin.pages.MarketPlacePage.plugin.tooltip.madeByStrapi": "Made 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.null": "Unable to verify compatibility with your Strapi version: \"{strapiAppVersion}\"",
|
||||
"admin.pages.MarketPlacePage.providers": "Providers",
|
||||
"admin.pages.MarketPlacePage.search.clear": "Clear the search",
|
||||
"admin.pages.MarketPlacePage.search.empty": "No result for \"{target}\"",
|
||||
|
@ -164,4 +164,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -110,5 +110,6 @@ coverage
|
||||
license.txt
|
||||
exports
|
||||
*.cache
|
||||
dist
|
||||
build
|
||||
.strapi-updater.json
|
||||
|
Loading…
x
Reference in New Issue
Block a user