mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Refactor/make styles batch 6 part 3 (#2823)
Last set of components refactoring for batch 6
This commit is contained in:
		
							parent
							
								
									005e4b6858
								
							
						
					
					
						commit
						94c90b7731
					
				| @ -29,6 +29,7 @@ interface IPermissionIconButtonProps { | ||||
| 
 | ||||
| interface IButtonProps extends IPermissionIconButtonProps { | ||||
|     onClick: (event: React.SyntheticEvent) => void; | ||||
|     style?: React.CSSProperties; | ||||
| } | ||||
| 
 | ||||
| interface ILinkProps extends IPermissionIconButtonProps { | ||||
| @ -107,6 +108,7 @@ const PermissionIconButton = (props: IButtonProps | ILinkProps) => { | ||||
|             /> | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     return <RootPermissionIconButton {...props} />; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -1,39 +1,36 @@ | ||||
| import { makeStyles } from 'tss-react/mui'; | ||||
| import Input from 'component/common/Input/Input'; | ||||
| import { TextField, Button, styled } from '@mui/material'; | ||||
| 
 | ||||
| export const useStyles = makeStyles()(theme => ({ | ||||
|     form: { | ||||
|         display: 'flex', | ||||
|         flexDirection: 'column', | ||||
|         height: '100%', | ||||
|     }, | ||||
|     container: { | ||||
|         maxWidth: '400px', | ||||
|     }, | ||||
|     input: { width: '100%', marginBottom: '1rem' }, | ||||
|     label: { | ||||
|         minWidth: '300px', | ||||
|         [theme.breakpoints.down(600)]: { | ||||
|             minWidth: 'auto', | ||||
|         }, | ||||
|     }, | ||||
|     buttonContainer: { | ||||
|         marginTop: 'auto', | ||||
|         display: 'flex', | ||||
|         justifyContent: 'flex-end', | ||||
|     }, | ||||
|     cancelButton: { | ||||
|         marginLeft: '1.5rem', | ||||
|     }, | ||||
|     inputDescription: { | ||||
|         marginBottom: '0.5rem', | ||||
|     }, | ||||
|     permissionErrorContainer: { | ||||
|         position: 'relative', | ||||
|     }, | ||||
|     errorMessage: { | ||||
|         fontSize: theme.fontSizes.smallBody, | ||||
|         color: theme.palette.error.main, | ||||
|         position: 'absolute', | ||||
|         top: '-8px', | ||||
|     }, | ||||
| export const StyledForm = styled('form')(() => ({ | ||||
|     display: 'flex', | ||||
|     flexDirection: 'column', | ||||
|     height: '100%', | ||||
| })); | ||||
| 
 | ||||
| export const StyledContainer = styled('div')(() => ({ | ||||
|     maxWidth: '400px', | ||||
| })); | ||||
| 
 | ||||
| export const StyledDescription = styled('p')(({ theme }) => ({ | ||||
|     marginBottom: theme.spacing(1), | ||||
| })); | ||||
| 
 | ||||
| export const StyledInput = styled(Input)(({ theme }) => ({ | ||||
|     width: '100%', | ||||
|     marginBottom: theme.spacing(2), | ||||
| })); | ||||
| 
 | ||||
| export const StyledTextField = styled(TextField)(({ theme }) => ({ | ||||
|     width: '100%', | ||||
|     marginBottom: theme.spacing(2), | ||||
| })); | ||||
| 
 | ||||
| export const StyledButtonContainer = styled('div')(() => ({ | ||||
|     marginTop: 'auto', | ||||
|     display: 'flex', | ||||
|     justifyContent: 'flex-end', | ||||
| })); | ||||
| 
 | ||||
| export const StyledButton = styled(Button)(({ theme }) => ({ | ||||
|     marginLeft: theme.spacing(3), | ||||
| })); | ||||
|  | ||||
| @ -1,9 +1,14 @@ | ||||
| import Input from 'component/common/Input/Input'; | ||||
| import { TextField, Button } from '@mui/material'; | ||||
| import { useStyles } from './ProjectForm.styles'; | ||||
| import React from 'react'; | ||||
| import { trim } from 'component/common/util'; | ||||
| 
 | ||||
| import { | ||||
|     StyledForm, | ||||
|     StyledContainer, | ||||
|     StyledDescription, | ||||
|     StyledInput, | ||||
|     StyledTextField, | ||||
|     StyledButtonContainer, | ||||
|     StyledButton, | ||||
| } from './ProjectForm.styles'; | ||||
| interface IProjectForm { | ||||
|     projectId: string; | ||||
|     projectName: string; | ||||
| @ -34,16 +39,11 @@ const ProjectForm: React.FC<IProjectForm> = ({ | ||||
|     validateProjectId, | ||||
|     clearErrors, | ||||
| }) => { | ||||
|     const { classes: styles } = useStyles(); | ||||
| 
 | ||||
|     return ( | ||||
|         <form onSubmit={handleSubmit} className={styles.form}> | ||||
|             <div className={styles.container}> | ||||
|                 <p className={styles.inputDescription}> | ||||
|                     What is your project Id? | ||||
|                 </p> | ||||
|                 <Input | ||||
|                     className={styles.input} | ||||
|         <StyledForm onSubmit={handleSubmit}> | ||||
|             <StyledContainer> | ||||
|                 <StyledDescription>What is your project Id?</StyledDescription> | ||||
|                 <StyledInput | ||||
|                     label="Project Id" | ||||
|                     value={projectId} | ||||
|                     onChange={e => setProjectId(trim(e.target.value))} | ||||
| @ -56,11 +56,10 @@ const ProjectForm: React.FC<IProjectForm> = ({ | ||||
|                     required | ||||
|                 /> | ||||
| 
 | ||||
|                 <p className={styles.inputDescription}> | ||||
|                 <StyledDescription> | ||||
|                     What is your project name? | ||||
|                 </p> | ||||
|                 <Input | ||||
|                     className={styles.input} | ||||
|                 </StyledDescription> | ||||
|                 <StyledInput | ||||
|                     label="Project name" | ||||
|                     value={projectName} | ||||
|                     onChange={e => setProjectName(e.target.value)} | ||||
| @ -70,11 +69,10 @@ const ProjectForm: React.FC<IProjectForm> = ({ | ||||
|                     required | ||||
|                 /> | ||||
| 
 | ||||
|                 <p className={styles.inputDescription}> | ||||
|                 <StyledDescription> | ||||
|                     What is your project description? | ||||
|                 </p> | ||||
|                 <TextField | ||||
|                     className={styles.input} | ||||
|                 </StyledDescription> | ||||
|                 <StyledTextField | ||||
|                     label="Project description" | ||||
|                     variant="outlined" | ||||
|                     multiline | ||||
| @ -82,15 +80,13 @@ const ProjectForm: React.FC<IProjectForm> = ({ | ||||
|                     value={projectDesc} | ||||
|                     onChange={e => setProjectDesc(e.target.value)} | ||||
|                 /> | ||||
|             </div> | ||||
|             </StyledContainer> | ||||
| 
 | ||||
|             <div className={styles.buttonContainer}> | ||||
|             <StyledButtonContainer> | ||||
|                 {children} | ||||
|                 <Button onClick={handleCancel} className={styles.cancelButton}> | ||||
|                     Cancel | ||||
|                 </Button> | ||||
|             </div> | ||||
|         </form> | ||||
|                 <StyledButton onClick={handleCancel}>Cancel</StyledButton> | ||||
|             </StyledButtonContainer> | ||||
|         </StyledForm> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -1,85 +1,83 @@ | ||||
| import { makeStyles } from 'tss-react/mui'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; | ||||
| import { flexRow } from 'themes/themeStyles'; | ||||
| import { styled } from '@mui/material'; | ||||
| 
 | ||||
| export const useStyles = makeStyles()(theme => ({ | ||||
|     projectInfo: { | ||||
|         width: '225px', | ||||
|         display: 'flex', | ||||
|         flexDirection: 'column', | ||||
|         alignItems: 'center', | ||||
|         boxShadow: 'none', | ||||
|         [theme.breakpoints.down('md')]: { | ||||
|             flexDirection: 'row', | ||||
|             alignItems: 'stretch', | ||||
|             width: '100%', | ||||
|             marginBottom: '1rem', | ||||
|         }, | ||||
|     }, | ||||
|     percentageContainer: { | ||||
|         display: 'flex', | ||||
|         justifyContent: 'center', | ||||
|         margin: '1rem 0', | ||||
|     }, | ||||
|     projectIcon: { | ||||
|         margin: '2rem 0', | ||||
|         [theme.breakpoints.down('md')]: { | ||||
|             margin: '0 0 0.25rem 0', | ||||
|             width: '53px', | ||||
|         }, | ||||
|     }, | ||||
|     subtitle: { | ||||
|         marginBottom: '1rem', | ||||
|     }, | ||||
|     emphazisedText: { | ||||
|         fontSize: '1.5rem', | ||||
|         marginBottom: '1rem', | ||||
|         [theme.breakpoints.down('md')]: { | ||||
|             fontSize: '1rem', | ||||
|             marginBottom: '2rem', | ||||
|         }, | ||||
|     }, | ||||
|     infoSection: { | ||||
|         margin: '0', | ||||
|         textAlign: 'center', | ||||
|         marginBottom: '1rem', | ||||
|         backgroundColor: theme.palette.background.paper, | ||||
|         borderRadius: theme.shape.borderRadiusLarge, | ||||
| export const StyledDivContainer = styled('div')(({ theme }) => ({ | ||||
|     ...flexRow, | ||||
|     width: '225px', | ||||
|     flexDirection: 'column', | ||||
|     boxShadow: 'none', | ||||
|     [theme.breakpoints.down('md')]: { | ||||
|         flexDirection: 'row', | ||||
|         alignItems: 'stretch', | ||||
|         width: '100%', | ||||
|         padding: '1.5rem 1rem 1.5rem 1rem', | ||||
|         [theme.breakpoints.down('md')]: { | ||||
|             margin: '0 0.25rem', | ||||
|             display: 'flex', | ||||
|             flexDirection: 'column', | ||||
|             alignItems: 'center', | ||||
|             justifyContent: 'center', | ||||
|             fontSize: '0.8rem', | ||||
|             position: 'relative', | ||||
|             padding: '0.8rem', | ||||
|             '&:first-of-type': { | ||||
|                 marginLeft: '0', | ||||
|             }, | ||||
|             '&:last-of-type': { | ||||
|                 marginRight: '0', | ||||
|             }, | ||||
|         marginBottom: theme.spacing(2), | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const StyledDivPercentageContainer = styled('div')(({ theme }) => ({ | ||||
|     display: 'flex', | ||||
|     justifyContent: 'center', | ||||
|     margin: theme.spacing(2, 0), | ||||
| })); | ||||
| 
 | ||||
| export const StyledDivInfoContainer = styled('div')(({ theme }) => ({ | ||||
|     margin: '0', | ||||
|     textAlign: 'center', | ||||
|     marginBottom: theme.spacing(2), | ||||
|     backgroundColor: theme.palette.background.paper, | ||||
|     borderRadius: theme.shape.borderRadiusLarge, | ||||
|     width: '100%', | ||||
|     padding: theme.spacing(3, 2, 3, 2), | ||||
|     [theme.breakpoints.down('md')]: { | ||||
|         margin: theme.spacing(0, 0.5), | ||||
|         ...flexRow, | ||||
|         flexDirection: 'column', | ||||
|         justifyContent: 'center', | ||||
|         fontSize: theme.fontSizes.smallBody, | ||||
|         position: 'relative', | ||||
|         padding: theme.spacing(1.5), | ||||
|         '&:first-of-type': { | ||||
|             marginLeft: '0', | ||||
|         }, | ||||
|     }, | ||||
|     arrowIcon: { | ||||
|         color: '#635dc5', | ||||
|         marginLeft: '0.5rem', | ||||
|     }, | ||||
|     permissionButtonShortDesc: { | ||||
|         transform: `translateY(-10px)`, | ||||
|     }, | ||||
|     infoLink: { | ||||
|         textDecoration: 'none', | ||||
|         color: '#635dc5', | ||||
|         [theme.breakpoints.down('md')]: { | ||||
|             position: 'absolute', | ||||
|             bottom: '5px', | ||||
|         }, | ||||
|     }, | ||||
|     linkText: { | ||||
|         [theme.breakpoints.down('md')]: { | ||||
|             display: 'none', | ||||
|         '&:last-of-type': { | ||||
|             marginRight: '0', | ||||
|         }, | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const StyledParagraphSubtitle = styled('p')(({ theme }) => ({ | ||||
|     marginBottom: theme.spacing(2), | ||||
| })); | ||||
| 
 | ||||
| export const StyledParagraphEmphasizedText = styled('p')(({ theme }) => ({ | ||||
|     fontSize: '1.5rem', | ||||
|     marginBottom: theme.spacing(2), | ||||
|     [theme.breakpoints.down('md')]: { | ||||
|         fontSize: theme.fontSizes.bodySize, | ||||
|         marginBottom: theme.spacing(4), | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const StyledSpanLinkText = styled('p')(({ theme }) => ({ | ||||
|     [theme.breakpoints.down('md')]: { | ||||
|         display: 'none', | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const StyledLink = styled(Link)(({ theme }) => ({ | ||||
|     textDecoration: 'none', | ||||
|     ...flexRow, | ||||
|     justifyContent: 'center', | ||||
|     color: theme.palette.primary.main, | ||||
|     [theme.breakpoints.down('md')]: { | ||||
|         position: 'absolute', | ||||
|         bottom: theme.spacing(1.5), | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const StyledArrowIcon = styled(ArrowForwardIcon)(({ theme }) => ({ | ||||
|     color: theme.palette.primary.main, | ||||
|     marginLeft: theme.spacing(1), | ||||
| })); | ||||
|  | ||||
| @ -1,14 +1,18 @@ | ||||
| import { useStyles } from './ProjectInfo.styles'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; | ||||
| import classnames from 'classnames'; | ||||
| 
 | ||||
| import { useThemeStyles } from 'themes/themeStyles'; | ||||
| import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||||
| import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| 
 | ||||
| import { DEFAULT_PROJECT_ID } from '../../../../hooks/api/getters/useDefaultProject/useDefaultProjectId'; | ||||
| import { | ||||
|     StyledDivContainer, | ||||
|     StyledDivInfoContainer, | ||||
|     StyledDivPercentageContainer, | ||||
|     StyledParagraphSubtitle, | ||||
|     StyledParagraphEmphasizedText, | ||||
|     StyledLink, | ||||
|     StyledSpanLinkText, | ||||
|     StyledArrowIcon, | ||||
| } from './ProjectInfo.styles'; | ||||
| 
 | ||||
| interface IProjectInfoProps { | ||||
|     id: string; | ||||
| @ -19,8 +23,6 @@ interface IProjectInfoProps { | ||||
| } | ||||
| 
 | ||||
| const ProjectInfo = ({ id, memberCount, health }: IProjectInfoProps) => { | ||||
|     const { classes: themeStyles } = useThemeStyles(); | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const { uiConfig } = useUiConfig(); | ||||
| 
 | ||||
|     let link = `/admin/users`; | ||||
| @ -31,69 +33,44 @@ const ProjectInfo = ({ id, memberCount, health }: IProjectInfoProps) => { | ||||
| 
 | ||||
|     return ( | ||||
|         <aside> | ||||
|             <div className={styles.projectInfo}> | ||||
|                 <div className={styles.infoSection}> | ||||
|                     <div data-loading className={styles.percentageContainer}> | ||||
|             <StyledDivContainer> | ||||
|                 <StyledDivInfoContainer> | ||||
|                     <StyledDivPercentageContainer> | ||||
|                         <PercentageCircle percentage={health} /> | ||||
|                     </div> | ||||
|                     <p className={styles.subtitle} data-loading> | ||||
|                     </StyledDivPercentageContainer> | ||||
|                     <StyledParagraphSubtitle data-loading> | ||||
|                         Overall health rating | ||||
|                     </p> | ||||
|                     <p className={styles.emphazisedText} data-loading> | ||||
|                     </StyledParagraphSubtitle> | ||||
|                     <StyledParagraphEmphasizedText data-loading> | ||||
|                         {health}% | ||||
|                     </p> | ||||
|                     <Link | ||||
|                         data-loading | ||||
|                         className={classnames( | ||||
|                             themeStyles.flexRow, | ||||
|                             themeStyles.justifyCenter, | ||||
|                             styles.infoLink | ||||
|                         )} | ||||
|                         to={`/projects/${id}/health`} | ||||
|                     > | ||||
|                         <span className={styles.linkText} data-loading> | ||||
|                     </StyledParagraphEmphasizedText> | ||||
|                     <StyledLink data-loading to={`/projects/${id}/health`}> | ||||
|                         <StyledSpanLinkText data-loading> | ||||
|                             view more{' '} | ||||
|                         </span> | ||||
|                         <ArrowForwardIcon | ||||
|                             data-loading | ||||
|                             className={styles.arrowIcon} | ||||
|                         /> | ||||
|                     </Link> | ||||
|                 </div> | ||||
|                         </StyledSpanLinkText> | ||||
|                         <StyledArrowIcon data-loading /> | ||||
|                     </StyledLink> | ||||
|                 </StyledDivInfoContainer> | ||||
|                 <ConditionallyRender | ||||
|                     condition={id !== DEFAULT_PROJECT_ID} | ||||
|                     show={ | ||||
|                         <div | ||||
|                             className={styles.infoSection} | ||||
|                             style={{ marginBottom: '0' }} | ||||
|                         > | ||||
|                             <p className={styles.subtitle} data-loading> | ||||
|                         <StyledDivInfoContainer style={{ marginBottom: '0' }}> | ||||
|                             <StyledParagraphSubtitle data-loading> | ||||
|                                 Project members | ||||
|                             </p> | ||||
|                             <p data-loading className={styles.emphazisedText}> | ||||
|                             </StyledParagraphSubtitle> | ||||
|                             <StyledParagraphEmphasizedText data-loading> | ||||
|                                 {memberCount} | ||||
|                             </p> | ||||
|                             <Link | ||||
|                                 data-loading | ||||
|                                 className={classnames( | ||||
|                                     themeStyles.flexRow, | ||||
|                                     themeStyles.justifyCenter, | ||||
|                                     styles.infoLink | ||||
|                                 )} | ||||
|                                 to={link} | ||||
|                             > | ||||
|                                 <span className={styles.linkText} data-loading> | ||||
|                             </StyledParagraphEmphasizedText> | ||||
|                             <StyledLink data-loading to={link}> | ||||
|                                 <StyledSpanLinkText data-loading> | ||||
|                                     view more{' '} | ||||
|                                 </span> | ||||
|                                 <ArrowForwardIcon | ||||
|                                     data-loading | ||||
|                                     className={styles.arrowIcon} | ||||
|                                 /> | ||||
|                             </Link> | ||||
|                         </div> | ||||
|                                 </StyledSpanLinkText> | ||||
|                                 <StyledArrowIcon data-loading /> | ||||
|                             </StyledLink> | ||||
|                         </StyledDivInfoContainer> | ||||
|                     } | ||||
|                 /> | ||||
|             </div> | ||||
|             </StyledDivContainer> | ||||
|         </aside> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| @ -1,63 +1,76 @@ | ||||
| import { makeStyles } from 'tss-react/mui'; | ||||
| import { styled } from '@mui/material'; | ||||
| import { Card, Box } from '@mui/material'; | ||||
| import { Delete, Edit } from '@mui/icons-material'; | ||||
| import { ReactComponent as ProjectIcon } from 'assets/icons/projectIcon.svg'; | ||||
| import { flexRow } from 'themes/themeStyles'; | ||||
| 
 | ||||
| export const useStyles = makeStyles()(theme => ({ | ||||
|     projectCard: { | ||||
|         padding: theme.spacing(1, 2, 2, 2), | ||||
|         width: '220px', | ||||
|         height: '204px', | ||||
|         display: 'flex', | ||||
|         flexDirection: 'column', | ||||
|         justifyContent: 'space-between', | ||||
|         margin: '0.5rem', | ||||
|         boxShadow: 'none', | ||||
|         border: '1px solid #efefef', | ||||
|         [theme.breakpoints.down('sm')]: { | ||||
|             justifyContent: 'center', | ||||
|         }, | ||||
|         '&:hover': { | ||||
|             transition: 'background-color 0.2s ease-in-out', | ||||
|             backgroundColor: theme.palette.projectCard.hover, | ||||
|         }, | ||||
| export const StyledProjectCard = styled(Card)(({ theme }) => ({ | ||||
|     padding: theme.spacing(1, 2, 2, 2), | ||||
|     width: '220px', | ||||
|     height: '204px', | ||||
|     display: 'flex', | ||||
|     flexDirection: 'column', | ||||
|     justifyContent: 'space-between', | ||||
|     margin: theme.spacing(1), | ||||
|     boxShadow: 'none', | ||||
|     border: `1px solid ${theme.palette.tertiary.contrast}`, | ||||
|     [theme.breakpoints.down('sm')]: { | ||||
|         justifyContent: 'center', | ||||
|     }, | ||||
|     header: { | ||||
|         display: 'flex', | ||||
|         alignItems: 'center', | ||||
|     }, | ||||
|     title: { | ||||
|         fontWeight: 'normal', | ||||
|         fontSize: '1rem', | ||||
|         lineClamp: 2, | ||||
|         display: '-webkit-box', | ||||
|         boxOrient: 'vertical', | ||||
|         textOverflow: 'ellipsis', | ||||
|         overflow: 'hidden', | ||||
|         alignItems: 'flex-start', | ||||
|     }, | ||||
| 
 | ||||
|     projectIcon: { | ||||
|         margin: '1rem auto', | ||||
|         width: '80px', | ||||
|         display: 'block', | ||||
|     }, | ||||
|     info: { | ||||
|         display: 'flex', | ||||
|         justifyContent: 'space-between', | ||||
|         fontSize: '0.8rem', | ||||
|     }, | ||||
|     infoBox: { | ||||
|         textAlign: 'center', | ||||
|     }, | ||||
|     infoStats: { | ||||
|         color: theme.palette.projectCard.textColor, | ||||
|         fontWeight: 'bold', | ||||
|     }, | ||||
|     actionsBtn: { | ||||
|         transform: 'translateX(15px)', | ||||
|         marginLeft: 'auto', | ||||
|         marginRight: theme.spacing(1), | ||||
|     }, | ||||
|     icon: { | ||||
|         color: theme.palette.grey[700], | ||||
|         marginRight: '0.5rem', | ||||
|     '&:hover': { | ||||
|         transition: 'background-color 0.2s ease-in-out', | ||||
|         backgroundColor: theme.palette.projectCard.hover, | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| export const StyledDivHeader = styled('div')(() => ({ | ||||
|     ...flexRow, | ||||
|     width: '100%', | ||||
| })); | ||||
| 
 | ||||
| export const StyledH2Title = styled('h2')(({ theme }) => ({ | ||||
|     fontWeight: 'normal', | ||||
|     fontSize: theme.fontSizes.bodySize, | ||||
|     lineClamp: 2, | ||||
|     display: '-webkit-box', | ||||
|     boxOrient: 'vertical', | ||||
|     textOverflow: 'ellipsis', | ||||
|     overflow: 'hidden', | ||||
|     alignItems: 'flex-start', | ||||
| })); | ||||
| 
 | ||||
| export const StyledBox = styled(Box)(() => ({ | ||||
|     ...flexRow, | ||||
|     marginRight: 'auto', | ||||
| })); | ||||
| 
 | ||||
| export const StyledEditIcon = styled(Edit)(({ theme }) => ({ | ||||
|     color: theme.palette.neutral.main, | ||||
|     marginRight: theme.spacing(1), | ||||
| })); | ||||
| 
 | ||||
| export const StyledDeleteIcon = styled(Delete)(({ theme }) => ({ | ||||
|     color: theme.palette.neutral.main, | ||||
|     marginRight: theme.spacing(1), | ||||
| })); | ||||
| 
 | ||||
| export const StyledProjectIcon = styled(ProjectIcon)(({ theme }) => ({ | ||||
|     margin: theme.spacing(2, 'auto'), | ||||
|     width: '80px', | ||||
|     display: 'block', | ||||
| })); | ||||
| 
 | ||||
| export const StyledDivInfo = styled('div')(({ theme }) => ({ | ||||
|     display: 'flex', | ||||
|     justifyContent: 'space-between', | ||||
|     fontSize: theme.fontSizes.smallerBody, | ||||
| })); | ||||
| 
 | ||||
| export const StyledDivInfoContainer = styled('div')(() => ({ | ||||
|     textAlign: 'center', | ||||
| })); | ||||
| 
 | ||||
| export const StyledParagraphInfo = styled('p')(({ theme }) => ({ | ||||
|     color: theme.palette.projectCard.textColor, | ||||
|     fontWeight: 'bold', | ||||
| })); | ||||
|  | ||||
| @ -1,10 +1,7 @@ | ||||
| import { Card, Menu, MenuItem } from '@mui/material'; | ||||
| import { useStyles } from './ProjectCard.styles'; | ||||
| import { Menu, MenuItem } from '@mui/material'; | ||||
| import MoreVertIcon from '@mui/icons-material/MoreVert'; | ||||
| import { ReactComponent as ProjectIcon } from 'assets/icons/projectIcon.svg'; | ||||
| import React, { SyntheticEvent, useContext, useState } from 'react'; | ||||
| import { useNavigate } from 'react-router-dom'; | ||||
| import { Delete, Edit } from '@mui/icons-material'; | ||||
| import { getProjectEditPath } from 'utils/routePathHelpers'; | ||||
| import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; | ||||
| import { | ||||
| @ -19,6 +16,20 @@ import { useFavoriteProjectsApi } from 'hooks/api/actions/useFavoriteProjectsApi | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { FavoriteIconButton } from 'component/common/FavoriteIconButton/FavoriteIconButton'; | ||||
| import { DeleteProjectDialogue } from '../Project/DeleteProject/DeleteProjectDialogue'; | ||||
| import { styled } from '@mui/material'; | ||||
| import { flexRow } from 'themes/themeStyles'; | ||||
| import { | ||||
|     StyledProjectCard, | ||||
|     StyledDivHeader, | ||||
|     StyledBox, | ||||
|     StyledH2Title, | ||||
|     StyledEditIcon, | ||||
|     StyledDeleteIcon, | ||||
|     StyledProjectIcon, | ||||
|     StyledDivInfo, | ||||
|     StyledDivInfoContainer, | ||||
|     StyledParagraphInfo, | ||||
| } from './ProjectCard.styles'; | ||||
| 
 | ||||
| interface IProjectCardProps { | ||||
|     name: string; | ||||
| @ -39,9 +50,8 @@ export const ProjectCard = ({ | ||||
|     id, | ||||
|     isFavorite = false, | ||||
| }: IProjectCardProps) => { | ||||
|     const { classes } = useStyles(); | ||||
|     const { hasAccess } = useContext(AccessContext); | ||||
|     const { isOss, uiConfig } = useUiConfig(); | ||||
|     const { isOss } = useUiConfig(); | ||||
|     const [anchorEl, setAnchorEl] = useState<Element | null>(null); | ||||
|     const [showDelDialog, setShowDelDialog] = useState(false); | ||||
|     const navigate = useNavigate(); | ||||
| @ -67,17 +77,20 @@ export const ProjectCard = ({ | ||||
|     }; | ||||
| 
 | ||||
|     return ( | ||||
|         <Card className={classes.projectCard} onMouseEnter={onHover}> | ||||
|             <div className={classes.header} data-loading> | ||||
|                 <FavoriteIconButton | ||||
|                     onClick={onFavorite} | ||||
|                     isFavorite={isFavorite} | ||||
|                     size="medium" | ||||
|                     sx={{ ml: -1 }} | ||||
|                 /> | ||||
|                 <h2 className={classes.title}>{name}</h2> | ||||
|         <StyledProjectCard onMouseEnter={onHover}> | ||||
|             <StyledDivHeader data-loading> | ||||
|                 <StyledBox> | ||||
|                     <FavoriteIconButton | ||||
|                         onClick={onFavorite} | ||||
|                         isFavorite={isFavorite} | ||||
|                         size="medium" | ||||
|                         sx={{ ml: -1 }} | ||||
|                     /> | ||||
|                     <StyledH2Title>{name}</StyledH2Title> | ||||
|                 </StyledBox> | ||||
| 
 | ||||
|                 <PermissionIconButton | ||||
|                     style={{ transform: 'translateX(7px)' }} | ||||
|                     permission={UPDATE_PROJECT} | ||||
|                     hidden={isOss()} | ||||
|                     projectId={id} | ||||
| @ -85,7 +98,6 @@ export const ProjectCard = ({ | ||||
|                     onClick={handleClick} | ||||
|                     tooltipProps={{ | ||||
|                         title: 'Options', | ||||
|                         className: classes.actionsBtn, | ||||
|                     }} | ||||
|                 > | ||||
|                     <MoreVertIcon /> | ||||
| @ -110,7 +122,7 @@ export const ProjectCard = ({ | ||||
|                             navigate(getProjectEditPath(id)); | ||||
|                         }} | ||||
|                     > | ||||
|                         <Edit className={classes.icon} /> | ||||
|                         <StyledEditIcon /> | ||||
|                         Edit project | ||||
|                     </MenuItem> | ||||
|                     <MenuItem | ||||
| @ -120,42 +132,42 @@ export const ProjectCard = ({ | ||||
|                         }} | ||||
|                         disabled={!canDeleteProject} | ||||
|                     > | ||||
|                         <Delete className={classes.icon} /> | ||||
|                         <StyledDeleteIcon /> | ||||
|                         {id === DEFAULT_PROJECT_ID && !canDeleteProject | ||||
|                             ? "You can't delete the default project" | ||||
|                             : 'Delete project'} | ||||
|                     </MenuItem> | ||||
|                 </Menu> | ||||
|             </div> | ||||
|             </StyledDivHeader> | ||||
|             <div data-loading> | ||||
|                 <ProjectIcon className={classes.projectIcon} /> | ||||
|                 <StyledProjectIcon /> | ||||
|             </div> | ||||
|             <div className={classes.info}> | ||||
|                 <div className={classes.infoBox}> | ||||
|                     <p className={classes.infoStats} data-loading> | ||||
|             <StyledDivInfo> | ||||
|                 <StyledDivInfoContainer> | ||||
|                     <StyledParagraphInfo data-loading> | ||||
|                         {featureCount} | ||||
|                     </p> | ||||
|                     </StyledParagraphInfo> | ||||
|                     <p data-loading>toggles</p> | ||||
|                 </div> | ||||
|                 <div className={classes.infoBox}> | ||||
|                     <p className={classes.infoStats} data-loading> | ||||
|                 </StyledDivInfoContainer> | ||||
|                 <StyledDivInfoContainer> | ||||
|                     <StyledParagraphInfo data-loading> | ||||
|                         {health}% | ||||
|                     </p> | ||||
|                     </StyledParagraphInfo> | ||||
|                     <p data-loading>health</p> | ||||
|                 </div> | ||||
|                 </StyledDivInfoContainer> | ||||
| 
 | ||||
|                 <ConditionallyRender | ||||
|                     condition={id !== DEFAULT_PROJECT_ID} | ||||
|                     show={ | ||||
|                         <div className={classes.infoBox}> | ||||
|                             <p className={classes.infoStats} data-loading> | ||||
|                         <StyledDivInfoContainer> | ||||
|                             <StyledParagraphInfo data-loading> | ||||
|                                 {memberCount} | ||||
|                             </p> | ||||
|                             </StyledParagraphInfo> | ||||
|                             <p data-loading>members</p> | ||||
|                         </div> | ||||
|                         </StyledDivInfoContainer> | ||||
|                     } | ||||
|                 /> | ||||
|             </div> | ||||
|             </StyledDivInfo> | ||||
|             <DeleteProjectDialogue | ||||
|                 project={id} | ||||
|                 open={showDelDialog} | ||||
| @ -164,6 +176,6 @@ export const ProjectCard = ({ | ||||
|                     setShowDelDialog(false); | ||||
|                 }} | ||||
|             /> | ||||
|         </Card> | ||||
|         </StyledProjectCard> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| @ -1,24 +0,0 @@ | ||||
| import { makeStyles } from 'tss-react/mui'; | ||||
| 
 | ||||
| export const useStyles = makeStyles()(theme => ({ | ||||
|     container: { | ||||
|         display: 'flex', | ||||
|         flexWrap: 'wrap', | ||||
|         [theme.breakpoints.down('sm')]: { | ||||
|             justifyContent: 'center', | ||||
|         }, | ||||
|     }, | ||||
|     apiError: { | ||||
|         maxWidth: '400px', | ||||
|         marginBottom: '1rem', | ||||
|     }, | ||||
|     cardLink: { | ||||
|         color: 'inherit', | ||||
|         textDecoration: 'none', | ||||
|         border: 'none', | ||||
|         padding: '0', | ||||
|         background: 'transparent', | ||||
|         fontFamily: theme.typography.fontFamily, | ||||
|         pointer: 'cursor', | ||||
|     }, | ||||
| })); | ||||
| @ -1,6 +1,5 @@ | ||||
| import { useMemo, useState } from 'react'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { useStyles } from './ProjectEnvironment.styles'; | ||||
| import { PageContent } from 'component/common/PageContent/PageContent'; | ||||
| import { PageHeader } from 'component/common/PageHeader/PageHeader'; | ||||
| import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions'; | ||||
| @ -38,6 +37,19 @@ const StyledAlert = styled(Alert)(({ theme }) => ({ | ||||
|     marginBottom: theme.spacing(4), | ||||
| })); | ||||
| 
 | ||||
| const StyledDivContainer = styled('div')(({ theme }) => ({ | ||||
|     display: 'flex', | ||||
|     flexWrap: 'wrap', | ||||
|     [theme.breakpoints.down('sm')]: { | ||||
|         justifyContent: 'center', | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| const StyledApiError = styled(ApiError)(({ theme }) => ({ | ||||
|     maxWidth: '400px', | ||||
|     marginBottom: theme.spacing(2), | ||||
| })); | ||||
| 
 | ||||
| const ProjectEnvironmentList = () => { | ||||
|     const projectId = useRequiredPathParam('projectId'); | ||||
|     const projectName = useProjectNameOrId(projectId); | ||||
| @ -56,7 +68,6 @@ const ProjectEnvironmentList = () => { | ||||
|     const [selectedEnvironment, setSelectedEnvironment] = | ||||
|         useState<IProjectEnvironment>(); | ||||
|     const [hideDialog, setHideDialog] = useState(false); | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const { isOss } = useUiConfig(); | ||||
| 
 | ||||
|     const projectEnvironments = useMemo<IProjectEnvironment[]>( | ||||
| @ -77,9 +88,8 @@ const ProjectEnvironmentList = () => { | ||||
| 
 | ||||
|     const renderError = () => { | ||||
|         return ( | ||||
|             <ApiError | ||||
|             <StyledApiError | ||||
|                 onClick={refetch} | ||||
|                 className={styles.apiError} | ||||
|                 text="Error fetching environments" | ||||
|             /> | ||||
|         ); | ||||
| @ -229,7 +239,7 @@ const ProjectEnvironmentList = () => { | ||||
|             <ConditionallyRender | ||||
|                 condition={uiConfig.flags.E} | ||||
|                 show={ | ||||
|                     <div className={styles.container}> | ||||
|                     <StyledDivContainer> | ||||
|                         <ConditionallyRender | ||||
|                             condition={Boolean(error)} | ||||
|                             show={renderError()} | ||||
| @ -305,7 +315,7 @@ const ProjectEnvironmentList = () => { | ||||
|                             setOpen={setHideDialog} | ||||
|                             onConfirm={onHideConfirm} | ||||
|                         /> | ||||
|                     </div> | ||||
|                     </StyledDivContainer> | ||||
|                 } | ||||
|                 elseShow={ | ||||
|                     <Alert security="success"> | ||||
|  | ||||
| @ -1,24 +0,0 @@ | ||||
| import { makeStyles } from 'tss-react/mui'; | ||||
| 
 | ||||
| export const useStyles = makeStyles()(theme => ({ | ||||
|     container: { | ||||
|         display: 'flex', | ||||
|         flexWrap: 'wrap', | ||||
|         [theme.breakpoints.down('sm')]: { | ||||
|             justifyContent: 'center', | ||||
|         }, | ||||
|     }, | ||||
|     apiError: { | ||||
|         maxWidth: '400px', | ||||
|         marginBottom: '1rem', | ||||
|     }, | ||||
|     cardLink: { | ||||
|         color: 'inherit', | ||||
|         textDecoration: 'none', | ||||
|         border: 'none', | ||||
|         padding: '0', | ||||
|         background: 'transparent', | ||||
|         fontFamily: theme.typography.fontFamily, | ||||
|         pointer: 'cursor', | ||||
|     }, | ||||
| })); | ||||
| @ -5,7 +5,6 @@ import { getProjectFetcher } from 'hooks/api/getters/useProject/getProjectFetche | ||||
| import useProjects from 'hooks/api/getters/useProjects/useProjects'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { ProjectCard } from '../ProjectCard/ProjectCard'; | ||||
| import { useStyles } from './ProjectList.styles'; | ||||
| import { IProjectCard } from 'interfaces/project'; | ||||
| import loadingData from './loadingData'; | ||||
| import { PageContent } from 'component/common/PageContent/PageContent'; | ||||
| @ -17,7 +16,7 @@ import { Add } from '@mui/icons-material'; | ||||
| import ApiError from 'component/common/ApiError/ApiError'; | ||||
| import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||||
| import { TablePlaceholder } from 'component/common/Table'; | ||||
| import { useMediaQuery } from '@mui/material'; | ||||
| import { useMediaQuery, styled } from '@mui/material'; | ||||
| import theme from 'themes/theme'; | ||||
| import { Search } from 'component/common/Search/Search'; | ||||
| import { PremiumFeature } from 'component/common/PremiumFeature/PremiumFeature'; | ||||
| @ -25,6 +24,29 @@ import { ITooltipResolverProps } from 'component/common/TooltipResolver/TooltipR | ||||
| import { ReactComponent as ProPlanIcon } from 'assets/icons/pro-enterprise-feature-badge.svg'; | ||||
| import { safeRegExp } from '@server/util/escape-regex'; | ||||
| 
 | ||||
| const StyledDivContainer = styled('div')(({ theme }) => ({ | ||||
|     display: 'flex', | ||||
|     flexWrap: 'wrap', | ||||
|     [theme.breakpoints.down('sm')]: { | ||||
|         justifyContent: 'center', | ||||
|     }, | ||||
| })); | ||||
| 
 | ||||
| const StyledApiError = styled(ApiError)(({ theme }) => ({ | ||||
|     maxWidth: '400px', | ||||
|     marginBottom: theme.spacing(2), | ||||
| })); | ||||
| 
 | ||||
| const StyledCardLink = styled(Link)(({ theme }) => ({ | ||||
|     color: 'inherit', | ||||
|     textDecoration: 'none', | ||||
|     border: 'none', | ||||
|     padding: '0', | ||||
|     background: 'transparent', | ||||
|     fontFamily: theme.typography.fontFamily, | ||||
|     pointer: 'cursor', | ||||
| })); | ||||
| 
 | ||||
| type PageQueryType = Partial<Record<'search', string>>; | ||||
| 
 | ||||
| type projectMap = { | ||||
| @ -71,7 +93,6 @@ function resolveCreateButtonData( | ||||
| export const ProjectListNew = () => { | ||||
|     const { hasAccess } = useContext(AccessContext); | ||||
|     const navigate = useNavigate(); | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const { projects, loading, error, refetch } = useProjects(); | ||||
|     const [fetchedProjects, setFetchedProjects] = useState<projectMap>({}); | ||||
|     const { isOss } = useUiConfig(); | ||||
| @ -127,11 +148,7 @@ export const ProjectListNew = () => { | ||||
| 
 | ||||
|     const renderError = () => { | ||||
|         return ( | ||||
|             <ApiError | ||||
|                 onClick={refetch} | ||||
|                 className={styles.apiError} | ||||
|                 text="Error fetching projects" | ||||
|             /> | ||||
|             <StyledApiError onClick={refetch} text="Error fetching projects" /> | ||||
|         ); | ||||
|     }; | ||||
| 
 | ||||
| @ -187,7 +204,7 @@ export const ProjectListNew = () => { | ||||
|             } | ||||
|         > | ||||
|             <ConditionallyRender condition={error} show={renderError()} /> | ||||
|             <div className={styles.container}> | ||||
|             <StyledDivContainer> | ||||
|                 <ConditionallyRender | ||||
|                     condition={filteredProjects.length < 1 && !loading} | ||||
|                     show={ | ||||
| @ -227,10 +244,9 @@ export const ProjectListNew = () => { | ||||
|                             elseShow={() => | ||||
|                                 filteredProjects.map( | ||||
|                                     (project: IProjectCard) => ( | ||||
|                                         <Link | ||||
|                                         <StyledCardLink | ||||
|                                             key={project.id} | ||||
|                                             to={`/projects/${project.id}`} | ||||
|                                             className={styles.cardLink} | ||||
|                                         > | ||||
|                                             <ProjectCard | ||||
|                                                 onHover={() => | ||||
| @ -247,14 +263,14 @@ export const ProjectListNew = () => { | ||||
|                                                 } | ||||
|                                                 isFavorite={project.favorite} | ||||
|                                             /> | ||||
|                                         </Link> | ||||
|                                         </StyledCardLink> | ||||
|                                     ) | ||||
|                                 ) | ||||
|                             } | ||||
|                         /> | ||||
|                     } | ||||
|                 /> | ||||
|             </div> | ||||
|             </StyledDivContainer> | ||||
|         </PageContent> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| @ -1,12 +0,0 @@ | ||||
| import { makeStyles } from 'tss-react/mui'; | ||||
| 
 | ||||
| export const useStyles = makeStyles()(theme => ({ | ||||
|     deleteInput: { | ||||
|         marginTop: '1rem', | ||||
|     }, | ||||
|     link: { | ||||
|         textDecoration: 'none', | ||||
|         color: theme.palette.primary.main, | ||||
|         fontWeight: theme.fontWeight.bold, | ||||
|     }, | ||||
| })); | ||||
| @ -1,9 +1,13 @@ | ||||
| import React, { useState } from 'react'; | ||||
| import { Dialogue } from 'component/common/Dialogue/Dialogue'; | ||||
| import Input from 'component/common/Input/Input'; | ||||
| import { useStyles } from './SegmentDeleteConfirm.styles'; | ||||
| import { ISegment } from 'interfaces/segment'; | ||||
| import { SEGMENT_DIALOG_NAME_ID } from 'utils/testIds'; | ||||
| import { styled } from '@mui/material'; | ||||
| 
 | ||||
| const StyledInput = styled(Input)(({ theme }) => ({ | ||||
|     marginTop: theme.spacing(2), | ||||
| })); | ||||
| 
 | ||||
| interface ISegmentDeleteConfirmProps { | ||||
|     segment: ISegment; | ||||
| @ -18,7 +22,6 @@ export const SegmentDeleteConfirm = ({ | ||||
|     onClose, | ||||
|     onRemove, | ||||
| }: ISegmentDeleteConfirmProps) => { | ||||
|     const { classes: styles } = useStyles(); | ||||
|     const [confirmName, setConfirmName] = useState(''); | ||||
| 
 | ||||
|     const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => | ||||
| @ -49,12 +52,11 @@ export const SegmentDeleteConfirm = ({ | ||||
|             </p> | ||||
| 
 | ||||
|             <form id={formId}> | ||||
|                 <Input | ||||
|                 <StyledInput | ||||
|                     autoFocus | ||||
|                     onChange={handleChange} | ||||
|                     value={confirmName} | ||||
|                     label="Segment name" | ||||
|                     className={styles.deleteInput} | ||||
|                     data-testid={SEGMENT_DIALOG_NAME_ID} | ||||
|                 /> | ||||
|             </form> | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| import { Dialogue } from 'component/common/Dialogue/Dialogue'; | ||||
| import { useStyles } from '../SegmentDeleteConfirm/SegmentDeleteConfirm.styles'; | ||||
| import { ISegment } from 'interfaces/segment'; | ||||
| import { IFeatureStrategy } from 'interfaces/strategy'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| @ -11,6 +10,12 @@ const StyledUl = styled('ul')({ | ||||
|     marginBottom: 0, | ||||
| }); | ||||
| 
 | ||||
| const StyledLink = styled(Link)(({ theme }) => ({ | ||||
|     textDecoration: 'none', | ||||
|     color: theme.palette.primary.main, | ||||
|     fontWeight: theme.fontWeight.bold, | ||||
| })); | ||||
| 
 | ||||
| interface ISegmentDeleteUsedSegmentProps { | ||||
|     segment: ISegment; | ||||
|     open: boolean; | ||||
| @ -24,8 +29,6 @@ export const SegmentDeleteUsedSegment = ({ | ||||
|     onClose, | ||||
|     strategies, | ||||
| }: ISegmentDeleteUsedSegmentProps) => { | ||||
|     const { classes: styles } = useStyles(); | ||||
| 
 | ||||
|     return ( | ||||
|         <Dialogue | ||||
|             title="You can't delete a segment that's currently in use" | ||||
| @ -40,7 +43,7 @@ export const SegmentDeleteUsedSegment = ({ | ||||
|             <StyledUl> | ||||
|                 {strategies?.map(strategy => ( | ||||
|                     <li key={strategy.id}> | ||||
|                         <Link | ||||
|                         <StyledLink | ||||
|                             to={formatEditStrategyPath( | ||||
|                                 strategy.projectId!, | ||||
|                                 strategy.featureName!, | ||||
| @ -49,11 +52,10 @@ export const SegmentDeleteUsedSegment = ({ | ||||
|                             )} | ||||
|                             target="_blank" | ||||
|                             rel="noopener noreferrer" | ||||
|                             className={styles.link} | ||||
|                         > | ||||
|                             {strategy.featureName!}{' '} | ||||
|                             {formatStrategyNameParens(strategy)} | ||||
|                         </Link> | ||||
|                         </StyledLink> | ||||
|                     </li> | ||||
|                 ))} | ||||
|             </StyledUl> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user