mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
feat: release template feedback module (#9614)
## About the changes Adds a release template feedback module to release templates:  It uses the Card component by defining a new variant of it. --------- Co-authored-by: Nuno Góis <github@nunogois.com>
This commit is contained in:
parent
b885a927e6
commit
380d2c2c5d
@ -1,6 +1,70 @@
|
||||
import { styled, Card as MUICard, Box, type CardProps } from '@mui/material';
|
||||
import {
|
||||
styled,
|
||||
Card as MUICard,
|
||||
Box,
|
||||
type CardProps,
|
||||
type Theme,
|
||||
type CSSObject,
|
||||
} from '@mui/material';
|
||||
|
||||
const StyledCard = styled(MUICard)(({ theme }) => ({
|
||||
type CardVariant = 'primary' | 'secondary';
|
||||
type CardComponent = 'card' | 'header' | 'body' | 'footer';
|
||||
type VariantProps = {
|
||||
[key in CardVariant]: {
|
||||
[key in CardComponent]: (theme: Theme) => CSSObject;
|
||||
};
|
||||
};
|
||||
|
||||
const variants: VariantProps = {
|
||||
primary: {
|
||||
card: (theme: Theme): CSSObject => ({
|
||||
backgroundColor: theme.palette.background.default,
|
||||
background: theme.palette.secondary.light,
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.neutral.light,
|
||||
},
|
||||
}),
|
||||
header: (theme: Theme): CSSObject => ({
|
||||
fontWeight: theme.typography.fontWeightRegular,
|
||||
}),
|
||||
body: (theme: Theme): CSSObject => ({
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.secondary,
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.neutral.light,
|
||||
},
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
}),
|
||||
footer: (theme: Theme): CSSObject => ({
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
background: theme.palette.background.elevation1,
|
||||
boxShadow: theme.boxShadows.accordionFooter,
|
||||
color: theme.palette.text.secondary,
|
||||
}),
|
||||
},
|
||||
secondary: {
|
||||
card: (theme: Theme): CSSObject => ({
|
||||
backgroundColor: theme.palette.secondary.light,
|
||||
borderColor: theme.palette.secondary.border,
|
||||
color: theme.palette.text.primary,
|
||||
}),
|
||||
header: (theme: Theme): CSSObject => ({
|
||||
fontWeight: theme.typography.fontWeightBold,
|
||||
}),
|
||||
body: (theme: Theme): CSSObject => ({
|
||||
backgroundColor: theme.palette.secondary.light,
|
||||
color: theme.palette.text.primary,
|
||||
}),
|
||||
footer: (theme: Theme): CSSObject => ({
|
||||
background: theme.palette.secondary.light,
|
||||
fontSize: theme.fontSizes.bodySize,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
const StyledCard = styled(MUICard, {
|
||||
shouldForwardProp: (prop) => prop !== 'cardVariant',
|
||||
})<{ cardVariant: CardVariant }>(({ theme, cardVariant }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
@ -11,30 +75,33 @@ const StyledCard = styled(MUICard)(({ theme }) => ({
|
||||
justifyContent: 'center',
|
||||
},
|
||||
transition: 'background-color 0.2s ease-in-out',
|
||||
backgroundColor: theme.palette.background.default,
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.neutral.light,
|
||||
},
|
||||
borderRadius: theme.shape.borderRadiusMedium,
|
||||
...variants[cardVariant].card(theme),
|
||||
}));
|
||||
|
||||
const StyledCardBody = styled(Box)(({ theme }) => ({
|
||||
const StyledCardBody = styled(Box, {
|
||||
shouldForwardProp: (prop) => prop !== 'cardVariant',
|
||||
})<{ cardVariant: CardVariant }>(({ theme, cardVariant }) => ({
|
||||
padding: theme.spacing(2),
|
||||
display: 'flex',
|
||||
flexFlow: 'column',
|
||||
height: '100%',
|
||||
position: 'relative',
|
||||
...variants[cardVariant].body(theme),
|
||||
}));
|
||||
|
||||
const StyledCardBodyHeader = styled(Box)(({ theme }) => ({
|
||||
const StyledCardBodyHeader = styled(Box, {
|
||||
shouldForwardProp: (prop) => prop !== 'cardVariant',
|
||||
})<{ cardVariant: CardVariant }>(({ theme, cardVariant }) => ({
|
||||
display: 'flex',
|
||||
gap: theme.spacing(1),
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
fontWeight: theme.typography.fontWeightRegular,
|
||||
fontSize: theme.typography.body1.fontSize,
|
||||
color: theme.palette.text.primary,
|
||||
lineHeight: '1.2',
|
||||
...variants[cardVariant].header(theme),
|
||||
}));
|
||||
|
||||
const StyledCardIconContainer = styled(Box)(({ theme }) => ({
|
||||
@ -58,23 +125,20 @@ const StyledCardActions = styled(Box)(({ theme }) => ({
|
||||
}));
|
||||
|
||||
const StyledCardBodyContent = styled(Box)(({ theme }) => ({
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
marginTop: theme.spacing(2),
|
||||
}));
|
||||
|
||||
const StyledCardFooter = styled(Box)(({ theme }) => ({
|
||||
const StyledCardFooter = styled(Box, {
|
||||
shouldForwardProp: (prop) => prop !== 'cardVariant',
|
||||
})<{ cardVariant: CardVariant }>(({ theme, cardVariant }) => ({
|
||||
padding: theme.spacing(0, 2),
|
||||
display: 'flex',
|
||||
background: theme.palette.background.elevation1,
|
||||
boxShadow: theme.boxShadows.accordionFooter,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
minHeight: theme.spacing(6.25),
|
||||
fontSize: theme.fontSizes.smallerBody,
|
||||
color: theme.palette.text.secondary,
|
||||
textWrap: 'nowrap',
|
||||
...variants[cardVariant].footer(theme),
|
||||
}));
|
||||
|
||||
interface ICardProps extends Omit<CardProps, 'title'> {
|
||||
@ -82,6 +146,7 @@ interface ICardProps extends Omit<CardProps, 'title'> {
|
||||
title?: React.ReactNode;
|
||||
headerActions?: React.ReactNode;
|
||||
footer?: React.ReactNode;
|
||||
cardVariant?: CardVariant;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
@ -90,12 +155,13 @@ export const Card = ({
|
||||
title,
|
||||
headerActions,
|
||||
footer,
|
||||
cardVariant = 'primary',
|
||||
children,
|
||||
...props
|
||||
}: ICardProps) => (
|
||||
<StyledCard {...props}>
|
||||
<StyledCardBody>
|
||||
<StyledCardBodyHeader>
|
||||
<StyledCard cardVariant={cardVariant} {...props}>
|
||||
<StyledCardBody cardVariant={cardVariant}>
|
||||
<StyledCardBodyHeader cardVariant={cardVariant}>
|
||||
{icon && (
|
||||
<StyledCardIconContainer>{icon}</StyledCardIconContainer>
|
||||
)}
|
||||
@ -108,6 +174,10 @@ export const Card = ({
|
||||
<StyledCardBodyContent>{children}</StyledCardBodyContent>
|
||||
)}
|
||||
</StyledCardBody>
|
||||
{footer && <StyledCardFooter>{footer}</StyledCardFooter>}
|
||||
{footer && (
|
||||
<StyledCardFooter cardVariant={cardVariant}>
|
||||
{footer}
|
||||
</StyledCardFooter>
|
||||
)}
|
||||
</StyledCard>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Grid, styled } from '@mui/material';
|
||||
import { ReleasePlanTemplateCard } from './ReleasePlanTemplateCard/ReleasePlanTemplateCard';
|
||||
import type { IReleasePlanTemplate } from 'interfaces/releasePlans';
|
||||
import { ReleasesFeedback } from './ReleasesFeedback';
|
||||
|
||||
const StyledGridItem = styled(Grid)({
|
||||
minHeight: '180px',
|
||||
@ -20,6 +21,15 @@ export const ReleasePlanTemplateList: React.FC<ITemplateList> = ({
|
||||
<ReleasePlanTemplateCard template={template} />
|
||||
</StyledGridItem>
|
||||
))}
|
||||
{templates.length > 0 && (
|
||||
<StyledGridItem key='feedback' item xs={6} md={4}>
|
||||
<ReleasesFeedback title='Release Templates'>
|
||||
We would love to get your feedback on the concept around
|
||||
release templates so we can bring it into our work going
|
||||
forward
|
||||
</ReleasesFeedback>
|
||||
</StyledGridItem>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,38 @@
|
||||
import { styled } from '@mui/material';
|
||||
import { Card } from 'component/common/Card/Card';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const StyledCardLink = styled(Link)(({ theme }) => ({
|
||||
textDecoration: 'none',
|
||||
fontWeight: theme.typography.fontWeightBold,
|
||||
color: theme.palette.links,
|
||||
'&:hover, &:focus': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
}));
|
||||
|
||||
const feedbackLink =
|
||||
'https://docs.google.com/forms/d/1ElbScYxbAhFcjQWgRinifoymYHeuXzqIoQXfpUVYGR8/preview';
|
||||
|
||||
export const ReleasesFeedback: React.FC<{
|
||||
title: string;
|
||||
children: React.ReactNode;
|
||||
}> = ({ title, children }: { title: string; children?: React.ReactNode }) => {
|
||||
return (
|
||||
<Card
|
||||
cardVariant='secondary'
|
||||
title={title}
|
||||
footer={
|
||||
<StyledCardLink
|
||||
to={feedbackLink}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
Give feedback
|
||||
</StyledCardLink>
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</Card>
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user