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