mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
Feat/add pro feature icon to oss projects (#2544)
<!-- Thanks for creating a PR! To make it easier for reviewers and everyone else to understand what your changes relate to, please add some relevant content to the headings below. Feel free to ignore or delete sections that you don't think are relevant. Thank you! ❤️ --> Add pro feature icon to oss projects. ## About the changes <!-- Describe the changes introduced. What are they and why are they being introduced? Feel free to also add screenshots or steps to view the changes if they're visual. --> <!-- Does it close an issue? Multiple? --> Closes # <!-- (For internal contributors): Does it relate to an issue on public roadmap? --> <!-- Relates to [roadmap](https://github.com/orgs/Unleash/projects/10) item: # --> ### Important files <!-- PRs can contain a lot of changes, but not all changes are equally important. Where should a reviewer start looking to get an overview of the changes? Are any files particularly important? --> ## Discussion points <!-- Anything about the PR you'd like to discuss before it gets merged? Got any questions or doubts? --> Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
parent
b8012a5ad8
commit
a992aca228
@ -0,0 +1,5 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.2608 0.811331C11.6574 0.375976 12.3426 0.375977 12.7392 0.811332L14.0529 2.25322C14.316 2.54202 14.7233 2.65114 15.0955 2.53259L16.9542 1.94073C17.5154 1.76203 18.1087 2.10458 18.2345 2.67993L18.6513 4.58549C18.7347 4.96716 19.0328 5.26527 19.4145 5.34875L21.3201 5.7655C21.8954 5.89133 22.238 6.48465 22.0593 7.04583L21.4674 8.90447C21.3489 9.27675 21.458 9.68397 21.7468 9.9471L23.1887 11.2608C23.624 11.6574 23.624 12.3426 23.1887 12.7392L21.7468 14.0529C21.458 14.316 21.3489 14.7233 21.4674 15.0955L22.0593 16.9542C22.238 17.5154 21.8954 18.1087 21.3201 18.2345L19.4145 18.6513C19.0328 18.7347 18.7347 19.0328 18.6513 19.4145L18.2345 21.3201C18.1087 21.8954 17.5154 22.238 16.9542 22.0593L15.0955 21.4674C14.7233 21.3489 14.316 21.458 14.0529 21.7468L12.7392 23.1887C12.3426 23.624 11.6574 23.624 11.2608 23.1887L9.9471 21.7468C9.68397 21.458 9.27675 21.3489 8.90447 21.4674L7.04583 22.0593C6.48465 22.238 5.89133 21.8954 5.7655 21.3201L5.34875 19.4145C5.26527 19.0328 4.96716 18.7347 4.58549 18.6513L2.67993 18.2345C2.10458 18.1087 1.76203 17.5154 1.94073 16.9542L2.53259 15.0955C2.65114 14.7233 2.54202 14.316 2.25322 14.0529L0.811331 12.7392C0.375976 12.3426 0.375977 11.6574 0.811332 11.2608L2.25322 9.9471C2.54202 9.68397 2.65114 9.27675 2.53259 8.90447L1.94073 7.04583C1.76203 6.48465 2.10458 5.89133 2.67993 5.7655L4.58549 5.34875C4.96716 5.26527 5.26527 4.96716 5.34875 4.58549L5.7655 2.67993C5.89133 2.10458 6.48465 1.76203 7.04583 1.94073L8.90447 2.53259C9.27675 2.65114 9.68397 2.54202 9.9471 2.25322L11.2608 0.811331Z" fill="#1A4049"/>
|
||||||
|
<path d="M10.4351 7.3042H7.30469V16.6955H16.696V7.3042H13.5656V13.5651H10.4351V7.3042Z" fill="white"/>
|
||||||
|
<path d="M13.5664 13.5649H16.6968V16.6954H13.5664V13.5649Z" fill="#817AFE"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
@ -1,10 +1,10 @@
|
|||||||
import { IconButton, IconButtonProps } from '@mui/material';
|
import { IconButton, IconButtonProps } from '@mui/material';
|
||||||
import React, { useContext, ReactNode } from 'react';
|
import React, { ReactNode, useContext } from 'react';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
import AccessContext from 'contexts/AccessContext';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
TooltipResolver,
|
|
||||||
ITooltipResolverProps,
|
ITooltipResolverProps,
|
||||||
|
TooltipResolver,
|
||||||
} from 'component/common/TooltipResolver/TooltipResolver';
|
} from 'component/common/TooltipResolver/TooltipResolver';
|
||||||
import { formatAccessText } from 'utils/formatAccessText';
|
import { formatAccessText } from 'utils/formatAccessText';
|
||||||
import { useId } from 'hooks/useId';
|
import { useId } from 'hooks/useId';
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
import { ReactComponent as ProPlanIcon } from 'assets/icons/pro-enterprise-feature-badge.svg';
|
||||||
|
import { Box, Link, styled, Typography } from '@mui/material';
|
||||||
|
|
||||||
|
export interface ProFeatureTooltipProps {
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProFeatureTooltipWrapper = styled(Box)(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
padding: theme.spacing(1, 1.5),
|
||||||
|
borderRadius: theme.shape.borderRadius,
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
width: '100%',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledTitle = styled(Typography)(({ theme }) => ({
|
||||||
|
display: 'inline-flex',
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
flexDirection: 'row',
|
||||||
|
marginBottom: theme.spacing(1),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const ProFeatureTooltip = ({ text }: ProFeatureTooltipProps) => {
|
||||||
|
return (
|
||||||
|
<ProFeatureTooltipWrapper>
|
||||||
|
<StyledTitle>
|
||||||
|
<ProPlanIcon />
|
||||||
|
<span style={{ marginLeft: '4px' }}>
|
||||||
|
Pro & Enterprise feature
|
||||||
|
</span>
|
||||||
|
</StyledTitle>
|
||||||
|
<Typography sx={{ alignContent: 'center' }}>{text}</Typography>
|
||||||
|
<Typography sx={{ alignContent: 'center' }}>
|
||||||
|
<Link target={'https://www.getunleash.io/plans'}>
|
||||||
|
Upgrade now
|
||||||
|
</Link>
|
||||||
|
</Typography>
|
||||||
|
</ProFeatureTooltipWrapper>
|
||||||
|
);
|
||||||
|
};
|
@ -1,11 +1,14 @@
|
|||||||
|
import React from 'react';
|
||||||
import { useMediaQuery } from '@mui/material';
|
import { useMediaQuery } from '@mui/material';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import PermissionButton from '../PermissionButton/PermissionButton';
|
import PermissionButton from '../PermissionButton/PermissionButton';
|
||||||
import PermissionIconButton from '../PermissionIconButton/PermissionIconButton';
|
import PermissionIconButton from '../PermissionIconButton/PermissionIconButton';
|
||||||
import React from 'react';
|
import { ITooltipResolverProps } from '../TooltipResolver/TooltipResolver';
|
||||||
|
|
||||||
interface IResponsiveButtonProps {
|
interface IResponsiveButtonProps {
|
||||||
Icon: React.ElementType;
|
Icon: React.ElementType;
|
||||||
|
endIcon?: React.ReactNode;
|
||||||
|
tooltipProps?: Omit<ITooltipResolverProps, 'children'>;
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
permission: string;
|
permission: string;
|
||||||
|
@ -1,20 +1,34 @@
|
|||||||
|
import React, { ReactNode } from 'react';
|
||||||
import { Tooltip, TooltipProps } from '@mui/material';
|
import { Tooltip, TooltipProps } from '@mui/material';
|
||||||
|
import { HtmlTooltip } from '../HtmlTooltip/HtmlTooltip';
|
||||||
|
|
||||||
export interface ITooltipResolverProps extends Omit<TooltipProps, 'title'> {
|
export interface ITooltipResolverProps extends Omit<TooltipProps, 'title'> {
|
||||||
title: string | undefined;
|
title?: string | undefined;
|
||||||
|
titleComponent?: ReactNode | undefined;
|
||||||
|
variant?: 'default' | 'white';
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TooltipResolver = ({
|
export const TooltipResolver = ({
|
||||||
title,
|
title,
|
||||||
children,
|
children,
|
||||||
|
variant = 'default',
|
||||||
|
titleComponent,
|
||||||
...rest
|
...rest
|
||||||
}: ITooltipResolverProps) => {
|
}: ITooltipResolverProps) => {
|
||||||
if (!title) {
|
if (!title && !titleComponent) {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (variant === 'white') {
|
||||||
|
return (
|
||||||
|
<HtmlTooltip {...rest} title={title || titleComponent} arrow>
|
||||||
|
{children}
|
||||||
|
</HtmlTooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip {...rest} title={title} arrow>
|
<Tooltip {...rest} title={title || titleComponent} arrow>
|
||||||
{children}
|
{children}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
|
@ -21,6 +21,9 @@ import { TablePlaceholder } from 'component/common/Table';
|
|||||||
import { useMediaQuery } from '@mui/material';
|
import { useMediaQuery } from '@mui/material';
|
||||||
import theme from 'themes/theme';
|
import theme from 'themes/theme';
|
||||||
import { Search } from 'component/common/Search/Search';
|
import { Search } from 'component/common/Search/Search';
|
||||||
|
import { ProFeatureTooltip } from '../../common/ProFeatureTooltip/ProFeatureTooltip';
|
||||||
|
import { ITooltipResolverProps } from '../../common/TooltipResolver/TooltipResolver';
|
||||||
|
import { ReactComponent as ProPlanIcon } from 'assets/icons/pro-enterprise-feature-badge.svg';
|
||||||
|
|
||||||
type PageQueryType = Partial<Record<'search', string>>;
|
type PageQueryType = Partial<Record<'search', string>>;
|
||||||
|
|
||||||
@ -28,20 +31,39 @@ type projectMap = {
|
|||||||
[index: string]: boolean;
|
[index: string]: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
function resolveCreateButtonData(isOss: boolean, hasAccess: boolean) {
|
interface ICreateButtonData {
|
||||||
|
disabled: boolean;
|
||||||
|
tooltip?: Omit<ITooltipResolverProps, 'children'>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveCreateButtonData(
|
||||||
|
isOss: boolean,
|
||||||
|
hasAccess: boolean
|
||||||
|
): ICreateButtonData {
|
||||||
if (isOss) {
|
if (isOss) {
|
||||||
return {
|
return {
|
||||||
title: 'You must be on a paid subscription to create new projects',
|
|
||||||
disabled: true,
|
disabled: true,
|
||||||
|
tooltip: {
|
||||||
|
titleComponent: (
|
||||||
|
<ProFeatureTooltip
|
||||||
|
text={
|
||||||
|
'To be able to add more projects you need to upgrade to Pro version'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
variant: 'white',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
} else if (!hasAccess) {
|
} else if (!hasAccess) {
|
||||||
return {
|
return {
|
||||||
title: 'You do not have permission to create new projects',
|
tooltip: {
|
||||||
|
title: 'You do not have permission to create new projects',
|
||||||
|
},
|
||||||
disabled: true,
|
disabled: true,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
title: 'Click to create a new project',
|
tooltip: { title: 'Click to create a new project' },
|
||||||
disabled: false,
|
disabled: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -174,10 +196,12 @@ export const ProjectListNew = () => {
|
|||||||
/>
|
/>
|
||||||
<ResponsiveButton
|
<ResponsiveButton
|
||||||
Icon={Add}
|
Icon={Add}
|
||||||
|
endIcon={<ProPlanIcon />}
|
||||||
onClick={() => navigate('/projects/create')}
|
onClick={() => navigate('/projects/create')}
|
||||||
maxWidth="700px"
|
maxWidth="700px"
|
||||||
permission={CREATE_PROJECT}
|
permission={CREATE_PROJECT}
|
||||||
disabled={createButtonData.disabled}
|
disabled={createButtonData.disabled}
|
||||||
|
tooltipProps={createButtonData.tooltip}
|
||||||
>
|
>
|
||||||
New project
|
New project
|
||||||
</ResponsiveButton>
|
</ResponsiveButton>
|
||||||
|
@ -8,7 +8,7 @@ import { EventOptions, PlausibleOptions } from 'plausible-tracker';
|
|||||||
* @see https://plausible.io/docs/custom-event-goals#2-create-a-custom-event-goal-in-your-plausible-analytics-account
|
* @see https://plausible.io/docs/custom-event-goals#2-create-a-custom-event-goal-in-your-plausible-analytics-account
|
||||||
* @example `'download | 'invite' | 'signup'`
|
* @example `'download | 'invite' | 'signup'`
|
||||||
**/
|
**/
|
||||||
type CustomEvents = 'invite';
|
type CustomEvents = 'invite' | 'upgrade_plan_clicked';
|
||||||
|
|
||||||
export const usePlausibleTracker = () => {
|
export const usePlausibleTracker = () => {
|
||||||
const plausible = useContext(PlausibleContext);
|
const plausible = useContext(PlausibleContext);
|
||||||
|
Loading…
Reference in New Issue
Block a user