mirror of
https://github.com/strapi/strapi.git
synced 2025-11-12 16:22:10 +00:00
feat(content-releases): added a purchase content releases page (#19455)
* feat(content-releases): first draft implementation PurchaseContentReleases * feat(content-releases): remove useless custom icon * feat(content-releases): fix typo and remove useless destructuring * feat(content-releases): add Icon as children and ignore the ts error * feat(content-releases): use badgeContent to show lock icon * feat(content-releases): change the typescript comment to avoid type errors
This commit is contained in:
parent
aa7c7ec672
commit
9bfbb6d4ba
@ -1,6 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { Box, Divider, Flex, FocusTrap, Typography } from '@strapi/design-system';
|
import { Box, Divider, Flex, FocusTrap, Icon, Typography } from '@strapi/design-system';
|
||||||
import {
|
import {
|
||||||
MainNav,
|
MainNav,
|
||||||
NavBrand,
|
NavBrand,
|
||||||
@ -12,7 +12,7 @@ import {
|
|||||||
NavUser,
|
NavUser,
|
||||||
} from '@strapi/design-system/v2';
|
} from '@strapi/design-system/v2';
|
||||||
import { useAppInfo, usePersistentState, useTracking } from '@strapi/helper-plugin';
|
import { useAppInfo, usePersistentState, useTracking } from '@strapi/helper-plugin';
|
||||||
import { Exit, Write } from '@strapi/icons';
|
import { Exit, Write, Lock } from '@strapi/icons';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import { NavLink as RouterNavLink, useLocation } from 'react-router-dom';
|
import { NavLink as RouterNavLink, useLocation } from 'react-router-dom';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
@ -49,6 +49,13 @@ const LinkUser = styled(RouterNavLink)<{ logout?: boolean }>`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const NavLinkWrapper = styled(Box)`
|
||||||
|
div:nth-child(2) {
|
||||||
|
/* remove badge background color */
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
interface LeftMenuProps extends Pick<Menu, 'generalSectionLinks' | 'pluginsSectionLinks'> {}
|
interface LeftMenuProps extends Pick<Menu, 'generalSectionLinks' | 'pluginsSectionLinks'> {}
|
||||||
|
|
||||||
const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }: LeftMenuProps) => {
|
const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }: LeftMenuProps) => {
|
||||||
@ -134,19 +141,24 @@ const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }: LeftMenuProps) =
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{pluginsSectionLinks.map((link) => {
|
{pluginsSectionLinks.map((link) => {
|
||||||
const Icon = link.icon;
|
const LinkIcon = link.icon;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<NavLinkWrapper key={link.to}>
|
||||||
<NavLink
|
<NavLink
|
||||||
as={RouterNavLink}
|
as={RouterNavLink}
|
||||||
// @ts-expect-error the props from the passed as prop are not inferred // joined together
|
|
||||||
to={link.to}
|
to={link.to}
|
||||||
key={link.to}
|
icon={<LinkIcon />}
|
||||||
icon={<Icon />}
|
|
||||||
onClick={() => handleClickOnLink(link.to)}
|
onClick={() => handleClickOnLink(link.to)}
|
||||||
|
// @ts-expect-error: badgeContent in the DS accept only strings
|
||||||
|
badgeContent={
|
||||||
|
link?.lockIcon ? (
|
||||||
|
<Icon width={`${15 / 16}rem`} height={`${15 / 16}rem`} as={Lock} />
|
||||||
|
) : undefined
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{formatMessage(link.intlLabel)}
|
{formatMessage(link.intlLabel)}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
</NavLinkWrapper>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</NavSection>
|
</NavSection>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ declare global {
|
|||||||
};
|
};
|
||||||
flags: {
|
flags: {
|
||||||
nps?: boolean;
|
nps?: boolean;
|
||||||
|
promoteEE?: boolean;
|
||||||
};
|
};
|
||||||
projectType: 'Community' | 'Enterprise';
|
projectType: 'Community' | 'Enterprise';
|
||||||
telemetryDisabled: boolean;
|
telemetryDisabled: boolean;
|
||||||
|
|||||||
@ -42,6 +42,23 @@ const admin: Plugin.Config.AdminInput = {
|
|||||||
name: `${pluginId}-link`,
|
name: `${pluginId}-link`,
|
||||||
Component: CMReleasesContainer,
|
Component: CMReleasesContainer,
|
||||||
});
|
});
|
||||||
|
} else if (
|
||||||
|
!window.strapi.features.isEnabled('cms-content-releases') &&
|
||||||
|
window.strapi?.flags?.promoteEE
|
||||||
|
) {
|
||||||
|
app.addMenuLink({
|
||||||
|
to: `/plugins/purchase-content-releases`,
|
||||||
|
icon: PaperPlane,
|
||||||
|
intlLabel: {
|
||||||
|
id: `${pluginId}.plugin.name`,
|
||||||
|
defaultMessage: 'Releases',
|
||||||
|
},
|
||||||
|
async Component() {
|
||||||
|
const { PurchaseContentReleases } = await import('./pages/PurchaseContentReleases');
|
||||||
|
return PurchaseContentReleases;
|
||||||
|
},
|
||||||
|
lockIcon: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async registerTrads({ locales }: { locales: string[] }) {
|
async registerTrads({ locales }: { locales: string[] }) {
|
||||||
|
|||||||
@ -0,0 +1,51 @@
|
|||||||
|
import { Box, Layout, Main, HeaderLayout, EmptyStateLayout } from '@strapi/design-system';
|
||||||
|
import { LinkButton } from '@strapi/design-system/v2';
|
||||||
|
import { ExternalLink, EmptyPermissions } from '@strapi/icons';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
const PurchaseContentReleases = () => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<Main>
|
||||||
|
<HeaderLayout
|
||||||
|
title={formatMessage({
|
||||||
|
id: 'content-releases.pages.Releases.title',
|
||||||
|
defaultMessage: 'Releases',
|
||||||
|
})}
|
||||||
|
subtitle={formatMessage({
|
||||||
|
id: 'content-releases.pages.PurchaseRelease.subTitle',
|
||||||
|
defaultMessage: 'Manage content updates and releases.',
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
<Box paddingLeft={10} paddingRight={10}>
|
||||||
|
<EmptyStateLayout
|
||||||
|
icon={<EmptyPermissions width="10rem" />}
|
||||||
|
content={formatMessage({
|
||||||
|
id: 'content-releases.pages.PurchaseRelease.not-available',
|
||||||
|
defaultMessage:
|
||||||
|
'Releases is only available as part of the Enterprise Edition. Upgrade to create and manage releases.',
|
||||||
|
})}
|
||||||
|
action={
|
||||||
|
<LinkButton
|
||||||
|
variant="default"
|
||||||
|
endIcon={<ExternalLink />}
|
||||||
|
href="https://strapi.io/pricing-self-hosted?utm_campaign=Growth-Experiments&utm_source=In-Product&utm_medium=Releases"
|
||||||
|
isExternal
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{formatMessage({
|
||||||
|
id: 'global.learn-more',
|
||||||
|
defaultMessage: 'Learn more',
|
||||||
|
})}
|
||||||
|
</LinkButton>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Main>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { PurchaseContentReleases };
|
||||||
@ -20,6 +20,8 @@
|
|||||||
"pages.Releases.max-limit-reached.title": "You have reached the {number} pending {number, plural, one {release} other {releases}} limit.",
|
"pages.Releases.max-limit-reached.title": "You have reached the {number} pending {number, plural, one {release} other {releases}} limit.",
|
||||||
"pages.Releases.max-limit-reached.message": "Upgrade to manage an unlimited number of releases.",
|
"pages.Releases.max-limit-reached.message": "Upgrade to manage an unlimited number of releases.",
|
||||||
"pages.Releases.max-limit-reached.action": "Explore plans",
|
"pages.Releases.max-limit-reached.action": "Explore plans",
|
||||||
|
"pages.PurchaseRelease.subTitle": "Manage content updates and releases.",
|
||||||
|
"pages.PurchaseRelease.not-available": "Releases is only available as part of the Enterprise Edition. Upgrade to create and manage releases.",
|
||||||
"header.actions.add-release": "New Release",
|
"header.actions.add-release": "New Release",
|
||||||
"header.actions.refresh": "Refresh",
|
"header.actions.refresh": "Refresh",
|
||||||
"header.actions.publish": "Publish",
|
"header.actions.publish": "Publish",
|
||||||
|
|||||||
@ -23,6 +23,7 @@ interface MenuItem extends Pick<LinkProps, 'to'> {
|
|||||||
notificationsCount?: number;
|
notificationsCount?: number;
|
||||||
Component?: ComponentModule;
|
Component?: ComponentModule;
|
||||||
exact?: boolean;
|
exact?: boolean;
|
||||||
|
lockIcon?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user