1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-03 01:18:43 +02:00

Update UI for strategies - segmentation and for mobile devices (#1189)

* fix: strategies rwd ui updates

* rwd updates to strategies

* add item numbers to strategies

* update strategy segmentation styles
This commit is contained in:
Tymoteusz Czech 2022-08-04 10:13:07 +02:00 committed by GitHub
parent 367d8a6a5a
commit 0b93776db6
20 changed files with 129 additions and 67 deletions

View File

@ -8,8 +8,7 @@ export const useStyles = makeStyles()(theme => ({
alignItems: 'center',
justifyContent: 'center',
marginRight: theme.spacing(1),
[theme.breakpoints.down(650)]: {
marginBottom: '1rem',
[theme.breakpoints.down(710)]: {
marginRight: 0,
},
},
@ -17,8 +16,8 @@ export const useStyles = makeStyles()(theme => ({
fill: '#fff',
},
accordion: {
border: `1px solid ${theme.palette.grey[400]}`,
borderRadius: '8px',
border: `1px solid ${theme.palette.dividerAlternative}`,
borderRadius: theme.shape.borderRadiusMedium,
backgroundColor: '#fff',
boxShadow: 'none',
margin: 0,
@ -27,6 +26,9 @@ export const useStyles = makeStyles()(theme => ({
'&:before': {
opacity: '0 !important',
},
'&:first-of-type, &:last-of-type': {
borderRadius: theme.shape.borderRadiusMedium,
},
},
accordionEdit: {
backgroundColor: '#F6F6FA',
@ -34,7 +36,10 @@ export const useStyles = makeStyles()(theme => ({
headerMetaInfo: {
display: 'flex',
alignItems: 'stretch',
[theme.breakpoints.down(710)]: { flexDirection: 'column' },
[theme.breakpoints.down(710)]: {
flexDirection: 'column',
alignItems: 'center',
},
},
headerContainer: {
display: 'flex',
@ -76,6 +81,9 @@ export const useStyles = makeStyles()(theme => ({
minWidth: '152px',
paddingRight: '0.5rem',
},
[theme.breakpoints.down(710)]: {
paddingRight: 0,
},
},
editingBadge: {
borderRadius: theme.shape.borderRadiusExtraLarge,

View File

@ -1,18 +1,12 @@
import { styled } from '@mui/material';
import { Box, styled, useTheme } from '@mui/material';
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender';
interface IStrategySeparatorProps {
text: 'AND' | 'OR';
}
const StyledContainer = styled('div')(({ theme }) => ({
height: theme.spacing(1),
position: 'relative',
width: '100%',
}));
const StyledContent = styled('div')(({ theme }) => ({
padding: theme.spacing(0.75, 1.5),
padding: theme.spacing(0.75, 1),
color: theme.palette.text.primary,
fontSize: theme.fontSizes.smallerBody,
backgroundColor: theme.palette.secondaryContainer,
@ -20,26 +14,38 @@ const StyledContent = styled('div')(({ theme }) => ({
position: 'absolute',
zIndex: theme.zIndex.fab,
top: '50%',
left: theme.spacing(3),
left: theme.spacing(2),
transform: 'translateY(-50%)',
lineHeight: 1,
}));
const StyledCenteredContent = styled(StyledContent)(({ theme }) => ({
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
backgroundColor: theme.palette.secondary.light,
backgroundColor: theme.palette.activityIndicators.primary,
border: `1px solid ${theme.palette.primary.border}`,
borderRadius: theme.shape.borderRadiusLarge,
}));
export const StrategySeparator = ({ text }: IStrategySeparatorProps) => (
<StyledContainer>
<ConditionallyRender
condition={text === 'AND'}
show={() => <StyledContent>{text}</StyledContent>}
elseShow={() => (
<StyledCenteredContent>{text}</StyledCenteredContent>
)}
/>
</StyledContainer>
);
export const StrategySeparator = ({ text }: IStrategySeparatorProps) => {
const theme = useTheme();
return (
<Box
sx={{
height: theme.spacing(text === 'AND' ? 1 : 1.5),
position: 'relative',
width: '100%',
}}
>
<ConditionallyRender
condition={text === 'AND'}
show={() => <StyledContent>{text}</StyledContent>}
elseShow={() => (
<StyledCenteredContent>{text}</StyledCenteredContent>
)}
/>
</Box>
);
};

View File

@ -6,6 +6,7 @@ export const useStyles = makeStyles()(theme => ({
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
paddingTop: theme.spacing(2),
},
title: {
fontSize: theme.fontSizes.bodySize,

View File

@ -161,7 +161,7 @@ export const FeatureStrategyEmpty = ({
display: 'grid',
width: '100%',
gap: 2,
gridTemplateColumns: '1fr 1fr',
gridTemplateColumns: { xs: '1fr', sm: '1fr 1fr' },
}}
>
<PresetCard

View File

@ -40,7 +40,14 @@ export const PresetCard: FC<IPresetCardProps> = ({
{children}
</Typography>
<Box sx={{ ml: 'auto', mt: 'auto', pt: 1 }}>
<Box
sx={{
ml: 'auto',
mt: 'auto',
pt: 1,
mr: { xs: 'auto', sm: 0 },
}}
>
<PermissionButton
permission={CREATE_FEATURE_STRATEGY}
projectId={projectId}

View File

@ -1,11 +1,6 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
title: {
margin: 0,
fontSize: theme.fontSizes.bodySize,
fontWeight: theme.fontWeight.bold,
},
divider: {
border: `1px dashed ${theme.palette.divider}`,
},

View File

@ -9,7 +9,7 @@ import { FeatureStrategySegmentList } from 'component/feature/FeatureStrategy/Fe
import { useStyles } from 'component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegment.styles';
import { SegmentDocsStrategyWarning } from 'component/segments/SegmentDocs/SegmentDocs';
import { useSegmentLimits } from 'hooks/api/getters/useSegmentLimits/useSegmentLimits';
import { Divider } from '@mui/material';
import { Divider, Typography } from '@mui/material';
interface IFeatureStrategySegmentProps {
segments: ISegment[];
@ -53,7 +53,9 @@ export const FeatureStrategySegment = ({
return (
<>
<h3 className={styles.title}>Segmentation</h3>
<Typography component="h3" sx={{ m: 0 }} variant="h3">
Segmentation
</Typography>
{atStrategySegmentsLimit && <SegmentDocsStrategyWarning />}
<p>Add a predefined segment to constrain this feature toggle:</p>
<AutocompleteBox

View File

@ -16,11 +16,13 @@ export const useStyles = makeStyles()(theme => ({
fontSize: theme.fontSizes.smallerBody,
border: '1px solid',
borderColor: theme.palette.grey[300],
paddingInline: '0.4rem',
marginBlock: '0.2rem',
display: 'grid',
padding: theme.spacing(0.75, 1),
display: 'block',
marginTop: 'auto',
marginBottom: 'auto',
alignItems: 'center',
borderRadius: theme.shape.borderRadius,
lineHeight: 1,
},
selectedSegmentsLabel: {
color: theme.palette.text.secondary,

View File

@ -1,3 +1,4 @@
import { Box, styled } from '@mui/material';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
import { MoveListItem, useDragItem } from 'hooks/useDragItem';
@ -13,6 +14,18 @@ interface IStrategyDraggableItemProps {
onDragAndDrop: MoveListItem;
}
const StyledIndexLabel = styled('div')(({ theme }) => ({
fontSize: theme.typography.fontSize,
color: theme.palette.text.secondary,
position: 'absolute',
display: 'none',
right: 'calc(100% + 6px)',
top: theme.spacing(2.5),
[theme.breakpoints.up('md')]: {
display: 'block',
},
}));
export const StrategyDraggableItem = ({
strategy,
index,
@ -23,17 +36,20 @@ export const StrategyDraggableItem = ({
const ref = useDragItem(index, onDragAndDrop);
return (
<div key={strategy.id} ref={ref}>
<Box key={strategy.id} ref={ref}>
<ConditionallyRender
condition={index > 0}
show={<StrategySeparator text="OR" />}
/>
<StrategyItem
strategy={strategy}
environmentId={environmentName}
otherEnvironments={otherEnvironments}
isDraggable
/>
</div>
<Box sx={{ position: 'relative' }}>
<StyledIndexLabel>{index + 1}</StyledIndexLabel>
<StrategyItem
strategy={strategy}
environmentId={environmentName}
otherEnvironments={otherEnvironments}
isDraggable
/>
</Box>
</Box>
);
};

View File

@ -4,7 +4,7 @@ export const useStyles = makeStyles()(theme => ({
container: {
width: '100%',
padding: theme.spacing(2, 3),
borderRadius: theme.shape.borderRadius,
borderRadius: theme.shape.borderRadiusMedium,
border: `1px solid ${theme.palette.divider}`,
},
chip: {

View File

@ -4,7 +4,7 @@ export const useStyles = makeStyles()(theme => ({
valueContainer: {
padding: theme.spacing(2, 3),
border: `1px solid ${theme.palette.dividerAlternative}`,
borderRadius: theme.shape.borderRadius,
borderRadius: theme.shape.borderRadiusMedium,
},
valueSeparator: {
color: theme.palette.grey[700],

View File

@ -17,6 +17,9 @@ export const useStyles = makeStyles()(theme => ({
borderBottom: `1px solid ${theme.palette.divider}`,
fontWeight: theme.typography.fontWeightMedium,
},
headerDraggable: {
paddingLeft: theme.spacing(1),
},
icon: {
fill: theme.palette.inactiveIcon,
},

View File

@ -1,6 +1,7 @@
import { DragIndicator, Edit } from '@mui/icons-material';
import { styled, useTheme, IconButton } from '@mui/material';
import { Link } from 'react-router-dom';
import classNames from 'classnames';
import { IFeatureEnvironment } from 'interfaces/featureToggle';
import { IFeatureStrategy } from 'interfaces/strategy';
import {
@ -52,7 +53,11 @@ export const StrategyItem = ({
return (
<div className={styles.container}>
<div className={styles.header}>
<div
className={classNames(styles.header, {
[styles.headerDraggable]: isDraggable,
})}
>
<ConditionallyRender
condition={Boolean(isDraggable)}
show={() => (
@ -60,6 +65,7 @@ export const StrategyItem = ({
<DragIndicator
titleAccess="Drag to reorder"
cursor="grab"
sx={{ color: 'neutral.main' }}
/>
</DragIcon>
)}

View File

@ -28,9 +28,13 @@ export const useStyles = makeStyles()(theme => ({
borderBottomLeftRadius: theme.shape.borderRadiusLarge,
borderBottomRightRadius: theme.shape.borderRadiusLarge,
borderBottom: `4px solid ${theme.palette.primary.light}`,
[theme.breakpoints.down('md')]: {
padding: theme.spacing(2, 1),
},
},
accordionDetailsDisabled: {
borderBottom: `4px solid ${theme.palette.dividerAlternative}`,
borderBottom: `4px solid ${theme.palette.neutral.border}`,
},
accordionBody: {
width: '100%',

View File

@ -85,18 +85,18 @@ const FeatureOverviewEnvironment = ({
maxWidth="100"
maxLength={15}
/>
<ConditionallyRender
condition={!env.enabled}
show={
<Chip
size="small"
variant="outlined"
label="Disabled"
sx={{ ml: 1 }}
/>
}
/>
</div>
<ConditionallyRender
condition={!env.enabled}
show={
<Chip
size="small"
variant="outlined"
label="Disabled"
sx={{ ml: 1 }}
/>
}
/>
</div>
<div className={styles.container}>
<FeatureStrategyMenu

View File

@ -14,7 +14,7 @@ const SeparatorContainer = styled('div')(({ theme }) => ({
transform: 'translateY(-50%)',
height: 2,
width: '100%',
backgroundColor: theme.palette.divider,
backgroundColor: theme.palette.dividerAlternative,
},
}));
@ -25,7 +25,7 @@ const SeparatorContent = styled('span')(({ theme }) => ({
background: theme.palette.secondaryContainer,
position: 'relative',
maxWidth: '80%',
color: theme.palette.text.secondary,
color: theme.palette.text.primary,
}));
export const SectionSeparator: FC = ({ children }) => (

View File

@ -3,6 +3,8 @@ import { Link } from 'react-router-dom';
import { DonutLarge } from '@mui/icons-material';
import { useStyles } from 'component/feature/FeatureView/FeatureOverview/FeatureOverviewSegment/FeatureOverviewSegment.styles';
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
interface IFeatureOverviewSegmentProps {
strategyId: string;
@ -20,8 +22,12 @@ export const FeatureOverviewSegment = ({
return (
<>
{segments.map(segment => (
{segments.map((segment, index) => (
<Fragment key={segment.id}>
<ConditionallyRender
condition={index > 0}
show={<StrategySeparator text="AND" />}
/>
<div className={styles.container}>
<DonutLarge color="secondary" sx={{ mr: 1 }} /> Segment:{' '}
<Link

View File

@ -81,9 +81,9 @@ const RolloutSlider = ({
<div className={classes.slider}>
<Typography
id="discrete-slider-always"
variant="subtitle2"
variant="h3"
gutterBottom
component="h2"
component="h3"
>
{name}
</Typography>

View File

@ -26,6 +26,10 @@ export default createTheme({
fontSize: '1.5rem',
lineHeight: 1.875,
},
h3: {
fontSize: '1rem',
fontWeight: '700',
},
caption: {
fontSize: `${12 / 16}rem`,
},
@ -128,6 +132,7 @@ export default createTheme({
recent: colors.green[100],
inactive: colors.orange[200],
abandoned: colors.red[200],
primary: colors.purple[100],
},
inactiveIcon: colors.grey[600],
},

View File

@ -46,13 +46,14 @@ declare module '@mui/material/styles' {
background: string;
};
/**
* For 'Seen' column on feature toggles list.
* For 'Seen' column on feature toggles list and other.
*/
activityIndicators: {
unknown: string;
recent: string;
inactive: string;
abandoned: string;
primary: string;
};
dividerAlternative: string;
/**