From b84df5c92ee81bc5c8150bb4e9c4a35d4a4380e1 Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:56:33 +0100 Subject: [PATCH] feat: info about unlimited projects option --- frontend/src/assets/img/upgradeProjects.png | Bin 0 -> 34470 bytes .../project/ProjectCard/ProjectCard.styles.ts | 1 + .../ProjectCardFooter/ProjectCardFooter.tsx | 4 +- .../ProjectCard/UpgradeProjectCard.tsx | 110 ++++++++++++++++++ .../project/ProjectList/ProjectGroup.tsx | 58 ++------- .../project/ProjectList/ProjectList.tsx | 64 ++++++---- .../ProjectsListHeader/ProjectsListHeader.tsx | 47 ++++++++ 7 files changed, 209 insertions(+), 75 deletions(-) create mode 100644 frontend/src/assets/img/upgradeProjects.png create mode 100644 frontend/src/component/project/ProjectCard/UpgradeProjectCard.tsx create mode 100644 frontend/src/component/project/ProjectList/ProjectsListHeader/ProjectsListHeader.tsx diff --git a/frontend/src/assets/img/upgradeProjects.png b/frontend/src/assets/img/upgradeProjects.png new file mode 100644 index 0000000000000000000000000000000000000000..183e56d0293d35bacb77095c250886b3cbb5a3aa GIT binary patch literal 34470 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 Aj{pDw literal 0 HcmV?d00001 diff --git a/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts b/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts index f83c93139e04..5025a55f7912 100644 --- a/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts +++ b/frontend/src/component/project/ProjectCard/ProjectCard.styles.ts @@ -32,6 +32,7 @@ export const StyledProjectCardBody = styled(Box)(({ theme }) => ({ flexFlow: 'column', justifyContent: 'space-between', height: '100%', + position: 'relative', })); export const StyledDivHeader = styled('div')(({ theme }) => ({ diff --git a/frontend/src/component/project/ProjectCard/ProjectCardFooter/ProjectCardFooter.tsx b/frontend/src/component/project/ProjectCard/ProjectCardFooter/ProjectCardFooter.tsx index 3ed959960000..13d8c38a6dc9 100644 --- a/frontend/src/component/project/ProjectCard/ProjectCardFooter/ProjectCardFooter.tsx +++ b/frontend/src/component/project/ProjectCard/ProjectCardFooter/ProjectCardFooter.tsx @@ -11,7 +11,7 @@ interface IProjectCardFooterProps { isFavorite?: boolean; children?: React.ReactNode; disabled?: boolean; - owners: IProjectOwnersProps['owners']; + owners?: IProjectOwnersProps['owners']; } const StyledFooter = styled(Box)<{ disabled: boolean }>( @@ -34,7 +34,7 @@ export const ProjectCardFooter: FC = ({ }) => { return ( - + {owners ? : null} {children} ); diff --git a/frontend/src/component/project/ProjectCard/UpgradeProjectCard.tsx b/frontend/src/component/project/ProjectCard/UpgradeProjectCard.tsx new file mode 100644 index 000000000000..4e06da3ba891 --- /dev/null +++ b/frontend/src/component/project/ProjectCard/UpgradeProjectCard.tsx @@ -0,0 +1,110 @@ +import { IconButton, styled, Tooltip, Typography } from '@mui/material'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import CloseIcon from '@mui/icons-material/Close'; +import { StyledProjectCard, StyledProjectCardBody } from './ProjectCard.styles'; +import { ProjectCardFooter } from './ProjectCardFooter/ProjectCardFooter'; +import upgradeProjects from 'assets/img/upgradeProjects.png'; +import { formatAssetPath } from 'utils/formatPath'; +import { useLocalStorageState } from 'hooks/useLocalStorageState'; + +const StyledFooter = styled('div')(({ theme }) => ({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + padding: theme.spacing(0.5, 1, 0.5, 2), + height: 53, +})); + +const StyledCloseButton = styled(IconButton)(({ theme }) => ({ + position: 'absolute', + top: theme.spacing(0.75), + right: theme.spacing(0.75), +})); + +const StyledInfo = styled('a')(({ theme }) => ({ + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + gap: theme.spacing(1), + textDecoration: 'none', + color: 'inherit', + height: '100%', + paddingTop: theme.spacing(0.5), +})); + +const StyledImage = styled('img')(({ theme }) => ({ + width: 95, + margin: theme.spacing(1), +})); + +export const UpgradeProjectCard = () => { + const [moreProjectsUpgrade, setMoreProjectsUpgrade] = useLocalStorageState< + 'open' | 'closed' + >('upgrade-projects:v1', 'open'); + + if (moreProjectsUpgrade === 'closed') { + return null; + } + + const onDismiss = () => { + setMoreProjectsUpgrade('closed'); + }; + + return ( + + + + + + + + + + More{' '} + + projects + {' '} + – +
+ easy collaboration +
+ +
+
+ + + + Get unlimited projects, and scale Unleash in your + organization + + + + + + +
+ ); +}; diff --git a/frontend/src/component/project/ProjectList/ProjectGroup.tsx b/frontend/src/component/project/ProjectList/ProjectGroup.tsx index f07f0ddb850e..66c12c6da990 100644 --- a/frontend/src/component/project/ProjectList/ProjectGroup.tsx +++ b/frontend/src/component/project/ProjectList/ProjectGroup.tsx @@ -1,32 +1,14 @@ import type { ComponentType, ReactNode } from 'react'; import { Link } from 'react-router-dom'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; -import { ProjectCard as NewProjectCard } from '../ProjectCard/ProjectCard'; +import { ProjectCard as DefaultProjectCard } from '../ProjectCard/ProjectCard'; import type { ProjectSchema } from 'openapi'; import loadingData from './loadingData'; import { TablePlaceholder } from 'component/common/Table'; -import { styled, Typography } from '@mui/material'; +import { styled } from '@mui/material'; import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; -import { flexColumn } from 'themes/themeStyles'; - -const StyledContainer = styled('article')(({ theme }) => ({ - ...flexColumn, - gap: theme.spacing(2), -})); - -const StyledHeaderContainer = styled('div')(({ theme }) => ({ - display: 'flex', - flexDirection: 'column-reverse', - gap: theme.spacing(2), - [theme.breakpoints.up('md')]: { - flexDirection: 'row', - alignItems: 'flex-end', - }, -})); - -const StyledHeaderTitle = styled('div')(() => ({ - flexGrow: 0, -})); +import { UpgradeProjectCard } from '../ProjectCard/UpgradeProjectCard'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; const StyledGridContainer = styled('div')(({ theme }) => ({ display: 'grid', @@ -56,41 +38,18 @@ type ProjectGroupProps = { }; export const ProjectGroup = ({ - sectionTitle, - sectionSubtitle, - HeaderActions, projects, loading, placeholder = 'No projects available.', ProjectCardComponent, link = true, }: ProjectGroupProps) => { - const ProjectCard = ProjectCardComponent ?? NewProjectCard; + const ProjectCard = ProjectCardComponent ?? DefaultProjectCard; + const { isOss } = useUiConfig(); const { searchQuery } = useSearchHighlightContext(); return ( - - - - - {sectionTitle} - - } - /> - - {sectionSubtitle} - - } - /> - - {HeaderActions} - + <> )} /> + {isOss() ? : null} } /> - + ); }; diff --git a/frontend/src/component/project/ProjectList/ProjectList.tsx b/frontend/src/component/project/ProjectList/ProjectList.tsx index b1bd18d4d895..56ec5ca024c3 100644 --- a/frontend/src/component/project/ProjectList/ProjectList.tsx +++ b/frontend/src/component/project/ProjectList/ProjectList.tsx @@ -16,6 +16,8 @@ import { ProjectCreationButton } from './ProjectCreationButton/ProjectCreationBu import { useGroupedProjects } from './hooks/useGroupedProjects'; import { useProjectsSearchAndSort } from './hooks/useProjectsSearchAndSort'; import { ProjectArchiveLink } from './ProjectArchiveLink/ProjectArchiveLink'; +import { ProjectsListHeader } from './ProjectsListHeader/ProjectsListHeader'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; const StyledApiError = styled(ApiError)(({ theme }) => ({ maxWidth: '500px', @@ -30,6 +32,7 @@ const StyledContainer = styled('div')(({ theme }) => ({ export const ProjectList = () => { const { projects, loading, error, refetch } = useProjects(); + const { isOss } = useUiConfig(); const isSmallScreen = useMediaQuery(theme.breakpoints.down('md')); @@ -63,7 +66,7 @@ export const ProjectList = () => { actions={ <> { } > { )} /> - - setState({ - sortBy: sortBy as typeof state.sortBy, - }) - } +
+ + setState({ + sortBy: sortBy as typeof state.sortBy, + }) + } + /> + } + > + My projects + + +
+ {!isOss() ? ( +
+ + Other projects + + - } - loading={loading} - projects={groupedProjects.myProjects} - /> - - +
+ ) : null}
diff --git a/frontend/src/component/project/ProjectList/ProjectsListHeader/ProjectsListHeader.tsx b/frontend/src/component/project/ProjectList/ProjectsListHeader/ProjectsListHeader.tsx new file mode 100644 index 000000000000..fdf630f479c5 --- /dev/null +++ b/frontend/src/component/project/ProjectList/ProjectsListHeader/ProjectsListHeader.tsx @@ -0,0 +1,47 @@ +import { styled, Typography } from '@mui/material'; +import type { FC, ReactNode } from 'react'; + +type ProjectsListHeaderProps = { + children?: ReactNode; + subtitle?: string; + actions?: ReactNode; +}; + +const StyledHeaderContainer = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'column-reverse', + gap: theme.spacing(2), + [theme.breakpoints.up('md')]: { + flexDirection: 'row', + alignItems: 'flex-end', + }, + marginBottom: theme.spacing(2), +})); + +const StyledHeaderTitle = styled('div')(() => ({ + flexGrow: 0, +})); + +export const ProjectsListHeader: FC = ({ + children, + subtitle, + actions, +}) => { + return ( + + + {children ? ( + + {children} + + ) : null} + {subtitle ? ( + + {subtitle} + + ) : null} + + {actions} + + ); +};