diff --git a/frontend/src/assets/img/releaseManagementPreview.svg b/frontend/src/assets/img/releaseManagementPreview.svg
deleted file mode 100644
index 4416fd606c..0000000000
--- a/frontend/src/assets/img/releaseManagementPreview.svg
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend/src/assets/img/releaseTemplatePreview.svg b/frontend/src/assets/img/releaseTemplatePreview.svg
new file mode 100644
index 0000000000..59980382f5
--- /dev/null
+++ b/frontend/src/assets/img/releaseTemplatePreview.svg
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash.tsx
index da6a0369d6..37f7cbb2ce 100644
--- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash.tsx
+++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash.tsx
@@ -23,7 +23,7 @@ import MonitorHeartIcon from '@mui/icons-material/MonitorHeartOutlined';
import { useNavigate } from 'react-router-dom';
import { formatAssetPath } from 'utils/formatPath';
import FactCheckOutlinedIcon from '@mui/icons-material/FactCheckOutlined';
-import { ReactComponent as ReleaseManagementPreview } from 'assets/img/releaseManagementPreview.svg';
+import { ReactComponent as ReleaseManagementPreview } from 'assets/img/releaseTemplatePreview.svg';
const StyledNewInUnleash = styled('div')(({ theme }) => ({
margin: theme.spacing(2, 0, 1, 0),
@@ -165,25 +165,14 @@ export const NewInUnleash = ({
},
{
label: 'Release templates',
- summary: 'Save time with release plans',
+ summary: 'Save time and optimize your process',
icon: ,
preview: ,
onCheckItOut: () => navigate('/release-templates'),
+ docsLink: 'https://docs.getunleash.io/reference/release-templates',
show: isEnterprise() && releasePlansEnabled,
- beta: true,
- longDescription: (
- <>
-
- Instead of having to set up the same strategies again
- and again, you can now create templates with milestones
- of how you want to rollout features to your users.
-
-
- Once you have set it up, just apply your release plan to
- a flag, and you are ready to rollout!
-
- >
- ),
+ beta: false,
+ popout: true,
},
];
@@ -229,6 +218,7 @@ export const NewInUnleash = ({
preview,
summary,
beta = false,
+ popout = false,
}) => (
),
)}
diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashDialog.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashDialog.tsx
new file mode 100644
index 0000000000..d14408bb68
--- /dev/null
+++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashDialog.tsx
@@ -0,0 +1,222 @@
+import OpenInNew from '@mui/icons-material/OpenInNew';
+import {
+ Badge,
+ Box,
+ Button,
+ ClickAwayListener,
+ Dialog,
+ IconButton,
+ Link,
+ styled,
+ Tooltip,
+ Typography,
+} from '@mui/material';
+import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
+import type { Link as RouterLink } from 'react-router-dom';
+import type { FC, ReactNode } from 'react';
+import Close from '@mui/icons-material/Close';
+
+const StyledLargeHeader = styled(Typography)(({ theme }) => ({
+ fontFamily: theme.typography.fontFamily,
+ fontSize: theme.typography.h1.fontSize,
+ fontWeight: theme.typography.fontWeightLight,
+ color: theme.palette.text.primary,
+ margin: 0,
+}));
+
+const StyledPreHeader = styled('div')(({ theme }) => ({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ gap: theme.spacing(1),
+ color: theme.palette.neutral.main,
+ fontFamily: theme.typography.fontFamily,
+ fontSize: theme.typography.h3.fontSize,
+ fontWeight: theme.typography.fontWeightBold,
+ padding: 0,
+ marginBottom: theme.spacing(0.5),
+}));
+
+const StyledMainTitle = styled('div')(({ theme }) => ({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ gap: theme.spacing(1),
+ padding: 0,
+ lineHeight: 1.2,
+}));
+
+const StyledLink = styled(Link)(({ theme }) => ({
+ display: 'flex',
+ alignItems: 'center',
+ gap: theme.spacing(1),
+ padding: 0,
+ color: theme.palette.links,
+ fontWeight: theme.typography.fontWeightBold,
+ '&:hover, &:focus': {
+ textDecoration: 'underline',
+ },
+}));
+
+const StyledOpenInNew = styled(OpenInNew)(({ theme }) => ({
+ fontSize: theme.spacing(2.25),
+}));
+
+const CenteredPreview = styled(Box)(({ theme }) => ({
+ padding: theme.spacing(3),
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ '> svg': { display: 'block', width: '100%', height: 'auto' },
+}));
+
+const LongDescription = styled(Box)(({ theme }) => ({
+ display: 'flex',
+ flexDirection: 'column',
+ gap: theme.spacing(1.5),
+ ul: {
+ margin: 0,
+ paddingLeft: theme.spacing(2),
+ },
+}));
+
+const ReadMore = styled(Box)(({ theme }) => ({
+ paddingTop: theme.spacing(3),
+ paddingBottom: theme.spacing(1),
+}));
+
+const StyledCheckItOutButton = styled(Button)(({ theme }) => ({
+ marginTop: theme.spacing(2),
+}));
+
+const DialogCard = styled(Box)(({ theme }) => ({
+ backgroundColor: theme.palette.background.paper,
+ borderRadius: theme.shape.borderRadiusLarge,
+ padding: theme.spacing(4),
+ margin: theme.spacing(2),
+ display: 'flex',
+ flexDirection: 'column',
+ flex: 1,
+ boxShadow: theme.shadows[5],
+ maxWidth: theme.spacing(150),
+ width: '100%',
+ height: '100%',
+ overflow: 'auto',
+}));
+
+const StyledDialog = styled(Dialog)(() => ({
+ '& .MuiDialog-paper': {
+ backgroundColor: 'transparent',
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ boxShadow: 'none',
+ overflow: 'visible',
+ },
+}));
+
+const BottomActions = styled(Box)(({ theme }) => ({
+ display: 'flex',
+ justifyContent: 'flex-end',
+ alignItems: 'center',
+ paddingRight: theme.spacing(3),
+ gap: theme.spacing(2),
+ flexWrap: 'wrap',
+}));
+
+const StyledItemButtonClose = styled(IconButton)(({ theme }) => ({
+ padding: theme.spacing(0.25),
+}));
+
+export const NewInUnleashDialog: FC<{
+ title: string;
+ longDescription: ReactNode;
+ docsLink?: string;
+ onCheckItOut?: () => void;
+ open: boolean;
+ preview?: ReactNode;
+ onClose: () => void;
+ beta: boolean;
+}> = ({
+ title,
+ longDescription,
+ onCheckItOut,
+ docsLink,
+ preview,
+ open,
+ onClose,
+ beta,
+}) => (
+
+
+
+
+ {
+ onClose();
+ e.stopPropagation();
+ }}
+ size='small'
+ >
+
+
+
+
+ New in Unleash
+
+
+ {title}
+ Beta}
+ />
+
+
+ {longDescription}
+
+ {preview}}
+ />
+
+
+
+
+
+ Read more in our documentation
+
+
+ }
+ />
+
+ {
+ event.stopPropagation();
+ onClose();
+ onCheckItOut?.();
+ }}
+ >
+ Get Started
+
+ }
+ />
+
+
+
+
+);
diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashItem.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashItem.tsx
index ce95e916ee..2abf4d1a01 100644
--- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashItem.tsx
+++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashItem.tsx
@@ -1,18 +1,8 @@
-import type * as React from 'react';
import { type ReactNode, useState } from 'react';
-import {
- IconButton,
- ListItem,
- ListItemButton,
- styled,
- Tooltip,
- Typography,
-} from '@mui/material';
-import Close from '@mui/icons-material/Close';
+import { ListItem } from '@mui/material';
import { NewInUnleashTooltip } from './NewInUnleashTooltip';
-import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
-import { Badge } from 'component/common/Badge/Badge';
-import { Truncator } from 'component/common/Truncator/Truncator';
+import { NewInUnleashDialog } from './NewInUnleashDialog';
+import { NewInUnleashSideBarItem } from './NewInUnleashSideBarItem';
export type NewInUnleashItemDetails = {
label: string;
@@ -21,41 +11,12 @@ export type NewInUnleashItemDetails = {
onCheckItOut?: () => void;
docsLink?: string;
show: boolean;
- longDescription: ReactNode;
+ longDescription?: ReactNode;
preview?: ReactNode;
beta?: boolean;
+ popout?: boolean;
};
-const StyledItemButton = styled(ListItemButton)(({ theme }) => ({
- outline: `1px solid ${theme.palette.divider}`,
- borderRadius: theme.shape.borderRadiusMedium,
- padding: theme.spacing(1),
- width: '100%',
- display: 'flex',
- alignItems: 'start',
- gap: theme.spacing(1),
- fontSize: theme.fontSizes.smallBody,
- '& > svg': {
- width: theme.spacing(3),
- height: theme.spacing(3),
- },
-}));
-
-const LabelWithSummary = styled('div')(({ theme }) => ({
- flex: 1,
-}));
-
-const StyledItemTitle = styled('div')(({ theme }) => ({
- display: 'flex',
- gap: theme.spacing(1),
- alignItems: 'center',
- height: theme.spacing(3),
-}));
-
-const StyledItemButtonClose = styled(IconButton)(({ theme }) => ({
- padding: theme.spacing(0.25),
-}));
-
interface INewInUnleashItemProps
extends Omit {
onClick: () => void;
@@ -88,6 +49,7 @@ export const NewInUnleashItem = ({
preview,
summary,
beta,
+ popout,
}: INewInUnleashItemProps) => {
const { open, handleTooltipOpen, handleTooltipClose } = useTooltip();
@@ -96,51 +58,55 @@ export const NewInUnleashItem = ({
onDismiss();
};
+ const onOpen = () => {
+ onClick();
+ handleTooltipOpen();
+ };
+
return (
- {
- onClick();
- handleTooltipOpen();
- }}
- >
-
-
- {icon}
-
-
-
-
- {label}
-
-
- Beta}
- />
-
- {summary}
-
-
-
-
-
-
-
-
+
+ {popout ? (
+ <>
+
+
+ >
+ ) : (
+
+
+
+ )}
);
};
diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashSideBarItem.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashSideBarItem.tsx
new file mode 100644
index 0000000000..95de0bb6b4
--- /dev/null
+++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashSideBarItem.tsx
@@ -0,0 +1,90 @@
+import type * as React from 'react';
+import type { ReactNode } from 'react';
+import {
+ IconButton,
+ ListItemButton,
+ styled,
+ Tooltip,
+ Typography,
+} from '@mui/material';
+import Close from '@mui/icons-material/Close';
+import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
+import { Badge } from 'component/common/Badge/Badge';
+import { Truncator } from 'component/common/Truncator/Truncator';
+
+const StyledItemButton = styled(ListItemButton)(({ theme }) => ({
+ outline: `1px solid ${theme.palette.divider}`,
+ borderRadius: theme.shape.borderRadiusMedium,
+ padding: theme.spacing(1),
+ width: '100%',
+ display: 'flex',
+ alignItems: 'start',
+ gap: theme.spacing(1),
+ fontSize: theme.fontSizes.smallBody,
+ '& > svg': {
+ width: theme.spacing(3),
+ height: theme.spacing(3),
+ },
+}));
+
+const LabelWithSummary = styled('div')(({ theme }) => ({
+ flex: 1,
+}));
+
+const StyledItemButtonClose = styled(IconButton)(({ theme }) => ({
+ padding: theme.spacing(0.25),
+}));
+
+const StyledItemTitle = styled('div')(({ theme }) => ({
+ display: 'flex',
+ gap: theme.spacing(1),
+ alignItems: 'center',
+ height: theme.spacing(3),
+}));
+
+interface NewInUnleashSideBarItemProps {
+ label: string;
+ summary: string;
+ icon: ReactNode;
+ beta?: boolean;
+ onDismiss: (e: React.MouseEvent) => void;
+ onClick: (e: React.MouseEvent) => void;
+}
+
+export const NewInUnleashSideBarItem = ({
+ icon,
+ label,
+ summary,
+ beta = false,
+ onDismiss,
+ onClick,
+}: NewInUnleashSideBarItemProps) => {
+ return (
+
+ {icon}
+
+
+
+
+ {label}
+
+
+ Beta}
+ />
+
+ {summary}
+
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashTooltip.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashTooltip.tsx
index 9233ece2ce..f2e7523cc1 100644
--- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashTooltip.tsx
+++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashTooltip.tsx
@@ -179,6 +179,6 @@ export const NewInUnleashTooltip: FC<{
}
>
- {children}
+ {children}
);