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

Segment preview (#1194)

* segment preview

* fix: loading and font size inconsistencies

* update segment accordion styles
This commit is contained in:
Tymoteusz Czech 2022-08-04 14:44:18 +02:00 committed by GitHub
parent 672a3f0b92
commit b7de1fba52
19 changed files with 171 additions and 93 deletions

View File

@ -26,9 +26,6 @@ export const useStyles = makeStyles()(theme => ({
'&:before': {
opacity: '0 !important',
},
'&:first-of-type, &:last-of-type': {
borderRadius: theme.shape.borderRadiusMedium,
},
},
accordionEdit: {
backgroundColor: '#F6F6FA',

View File

@ -48,7 +48,7 @@ export const useStyles = makeStyles()(theme => ({
justifyContent: 'space-between',
alignItems: 'center',
fontWeight: theme.fontWeight.bold,
fontSize: theme.fontSizes.subHeader,
fontSize: theme.fontSizes.bodySize,
},
description: {
color: '#fff',

View File

@ -0,0 +1,45 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
width: '100%',
padding: theme.spacing(2, 3),
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-start',
fontSize: theme.fontSizes.smallBody,
border: `1px solid ${theme.palette.dividerAlternative}`,
position: 'relative',
borderRadius: '5px',
},
link: {
textDecoration: 'none',
marginLeft: theme.spacing(1),
'&:hover': {
textDecoration: 'underline',
},
},
accordion: {
border: `1px solid ${theme.palette.dividerAlternative}`,
borderRadius: theme.shape.borderRadiusMedium,
backgroundColor: '#fff',
boxShadow: 'none',
margin: 0,
},
accordionRoot: {
transition: 'all 0.1s ease',
},
accordionExpanded: {
backgroundColor: theme.palette.neutral.light,
},
previewButton: {
paddingTop: 0,
paddingBottom: 0,
marginLeft: 'auto',
fontSize: theme.fontSizes.smallBody,
},
summary: {
fontSize: theme.fontSizes.smallBody,
margin: theme.spacing(0.5, 0),
},
}));

View File

@ -0,0 +1,81 @@
import { useState, VFC } from 'react';
import { Link } from 'react-router-dom';
import { DonutLarge } from '@mui/icons-material';
import { ISegment } from 'interfaces/segment';
import {
Accordion,
AccordionDetails,
AccordionSummary,
Button,
Typography,
} from '@mui/material';
import { ConstraintAccordionList } from '../ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender';
import { useStyles } from './SegmentItem.styles';
interface ISegmentItemProps {
segment: ISegment;
isExpanded?: boolean;
}
export const SegmentItem: VFC<ISegmentItemProps> = ({
segment,
isExpanded,
}) => {
const { classes } = useStyles();
const [isOpen, setIsOpen] = useState(isExpanded || false);
return (
<Accordion
expanded={isOpen}
className={classes.accordion}
classes={{
root: classes.accordionRoot,
expanded: classes.accordionExpanded,
}}
>
<AccordionSummary
id={`segment-accordion-${segment.id}`}
className={classes.summary}
>
<DonutLarge color="secondary" sx={{ mr: 1 }} />
Segment:
<Link
to={`/segments/edit/${segment.id}`}
className={classes.link}
>
{segment.name}
</Link>
<ConditionallyRender
condition={!isExpanded}
show={
<Button
size="small"
variant="outlined"
onClick={() => setIsOpen(value => !value)}
className={classes.previewButton}
>
{isOpen ? 'Close preview' : 'Preview'}
</Button>
}
/>
</AccordionSummary>
<AccordionDetails sx={{ pt: 0 }}>
<ConditionallyRender
condition={segment!.constraints?.length > 0}
show={
<ConstraintAccordionList
constraints={segment!.constraints}
showLabel={false}
/>
}
elseShow={
<Typography>
This segment has no constraints.
</Typography>
}
/>
</AccordionDetails>
</Accordion>
);
};

View File

@ -26,6 +26,7 @@ const StyledCenteredContent = styled(StyledContent)(({ theme }) => ({
backgroundColor: theme.palette.activityIndicators.primary,
border: `1px solid ${theme.palette.primary.border}`,
borderRadius: theme.shape.borderRadiusLarge,
padding: theme.spacing(0.75, 1.5),
}));
export const StrategySeparator = ({ text }: IStrategySeparatorProps) => {

View File

@ -16,7 +16,7 @@ export const useStyles = makeStyles()(theme => ({
display: 'grid',
gridTemplateColumns: 'auto 1fr',
gridGap: '.5rem',
fontSize: theme.fontSizes.subHeader,
fontSize: theme.fontSizes.bodySize,
},
icon: {
color: theme.palette.primary.main,

View File

@ -3,5 +3,7 @@ import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
divider: {
border: `1px dashed ${theme.palette.divider}`,
marginTop: theme.spacing(1),
marginBottom: theme.spacing(2),
},
}));

View File

@ -12,10 +12,7 @@ export const useStyles = makeStyles()(theme => ({
gap: '0.5rem',
},
and: {
color: theme.palette.grey[600],
fontSize: theme.fontSizes.smallerBody,
border: '1px solid',
borderColor: theme.palette.grey[300],
padding: theme.spacing(0.75, 1),
display: 'block',
marginTop: 'auto',
@ -23,6 +20,8 @@ export const useStyles = makeStyles()(theme => ({
alignItems: 'center',
borderRadius: theme.shape.borderRadius,
lineHeight: 1,
color: theme.palette.text.primary,
backgroundColor: theme.palette.secondaryContainer,
},
selectedSegmentsLabel: {
color: theme.palette.text.secondary,

View File

@ -3,7 +3,7 @@ import { ISegment } from 'interfaces/segment';
import { useStyles } from 'component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentList.styles';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { FeatureStrategySegmentChip } from 'component/feature/FeatureStrategy/FeatureStrategySegment/FeatureStrategySegmentChip';
import { ConstraintAccordionList } from 'component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList';
import { SegmentItem } from 'component/common/SegmentItem/SegmentItem';
interface IFeatureStrategySegmentListProps {
segments: ISegment[];
@ -48,16 +48,10 @@ export const FeatureStrategySegmentList = ({
</Fragment>
))}
</div>
<ConditionallyRender
condition={Boolean(preview && preview.constraints.length === 0)}
show={() => <p>This segment has no constraints.</p>}
/>
<ConditionallyRender
condition={Boolean(preview)}
show={() => (
<ConstraintAccordionList
constraints={preview!.constraints}
/>
<SegmentItem segment={preview as ISegment} isExpanded />
)}
/>
</>

View File

@ -19,7 +19,7 @@ export const useStyles = makeStyles()(theme => ({
},
},
header: {
fontSize: theme.fontSizes.subHeader,
fontSize: theme.fontSizes.bodySize,
fontWeight: 'normal',
margin: 0,
marginBottom: '0.5rem',

View File

@ -31,7 +31,7 @@ export const useStyles = makeStyles()(theme => ({
percentage: {
color: theme.palette.primary.main,
textAlign: 'right',
fontSize: theme.fontSizes.subHeader,
fontSize: theme.fontSizes.bodySize,
},
percentageCircle: {
margin: '0 1rem',

View File

@ -19,7 +19,7 @@ const SeparatorContainer = styled('div')(({ theme }) => ({
}));
const SeparatorContent = styled('span')(({ theme }) => ({
fontSize: theme.fontSizes.subHeader,
fontSize: theme.fontSizes.bodySize,
textAlign: 'center',
padding: '0 1rem',
background: theme.palette.secondaryContainer,

View File

@ -28,7 +28,7 @@ export const useStyles = makeStyles()(theme => ({
alignItems: 'center',
},
header: {
fontSize: theme.fontSizes.subHeader,
fontSize: theme.fontSizes.bodySize,
fontWeight: 'normal',
margin: 0,
},

View File

@ -1,22 +0,0 @@
import { makeStyles } from 'tss-react/mui';
export const useStyles = makeStyles()(theme => ({
container: {
width: '100%',
padding: theme.spacing(2, 3),
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-start',
fontSize: theme.fontSizes.smallBody,
border: `1px solid ${theme.palette.dividerAlternative}`,
position: 'relative',
borderRadius: '5px',
},
link: {
textDecoration: 'none',
marginLeft: theme.spacing(1),
'&:hover': {
textDecoration: 'underline',
},
},
}));

View File

@ -1,10 +1,8 @@
import { Fragment } from 'react';
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';
import { SegmentItem } from '../../../../common/SegmentItem/SegmentItem';
interface IFeatureOverviewSegmentProps {
strategyId: string;
@ -13,7 +11,6 @@ interface IFeatureOverviewSegmentProps {
export const FeatureOverviewSegment = ({
strategyId,
}: IFeatureOverviewSegmentProps) => {
const { classes: styles } = useStyles();
const { segments } = useSegments(strategyId);
if (!segments || segments.length === 0) {
@ -28,21 +25,9 @@ export const FeatureOverviewSegment = ({
condition={index > 0}
show={<StrategySeparator text="AND" />}
/>
<div className={styles.container}>
<DonutLarge color="secondary" sx={{ mr: 1 }} /> Segment:{' '}
<Link
to={segmentPath(segment.id)}
className={styles.link}
>
{segment.name}
</Link>
</div>
<SegmentItem segment={segment} />
</Fragment>
))}
</>
);
};
const segmentPath = (segmentId: number): string => {
return `/segments/edit/${segmentId}`;
};

View File

@ -76,21 +76,6 @@ export const FeatureView = () => {
const activeTab = tabData.find(tab => tab.path === pathname) ?? tabData[0];
const renderTabs = () => {
return tabData.map((tab, index) => {
return (
<Tab
data-loading
key={tab.title}
label={tab.title}
value={tab.path}
onClick={() => navigate(tab.path)}
className={styles.tabButton}
/>
);
});
};
if (status === 404) {
return <FeatureNotFound />;
}
@ -168,7 +153,15 @@ export const FeatureView = () => {
indicatorColor="primary"
textColor="primary"
>
{renderTabs()}
{tabData.map(tab => (
<Tab
key={tab.title}
label={tab.title}
value={tab.path}
onClick={() => navigate(tab.path)}
className={styles.tabButton}
/>
))}
</Tabs>
</div>
</div>

View File

@ -80,21 +80,6 @@ const Project = () => {
/* eslint-disable-next-line */
}, []);
const renderTabs = () => {
return tabs.map(tab => {
return (
<Tab
data-loading
key={tab.title}
label={tab.title}
value={tab.path}
onClick={() => navigate(tab.path)}
className={styles.tabButton}
/>
);
});
};
return (
<div ref={ref}>
<div className={styles.header}>
@ -135,7 +120,15 @@ const Project = () => {
indicatorColor="primary"
textColor="primary"
>
{renderTabs()}
{tabs.map(tab => (
<Tab
key={tab.title}
label={tab.title}
value={tab.path}
onClick={() => navigate(tab.path)}
className={styles.tabButton}
/>
))}
</Tabs>
</div>
</div>

View File

@ -36,7 +36,6 @@ export default createTheme({
},
fontSizes: {
mainHeader: '1.25rem',
subHeader: '1.1rem',
bodySize: '1rem',
smallBody: `${14 / 16}rem`,
smallerBody: `${12 / 16}rem`,
@ -260,12 +259,24 @@ export default createTheme({
},
},
},
MuiAccordion: {
styleOverrides: {
root: ({ theme }) => ({
'&:first-of-type, &:last-of-type': {
borderRadius: theme.shape.borderRadiusMedium,
},
}),
},
},
MuiAccordionSummary: {
styleOverrides: {
root: {
'& > .MuiAccordionSummary-content.Mui-expanded': {
margin: '12px 0',
},
'&.Mui-expanded': {
minHeight: '0',
},
},
},
},

View File

@ -5,7 +5,6 @@ declare module '@mui/material/styles' {
*/
fontSizes: {
mainHeader: string;
subHeader: string;
bodySize: string;
smallBody: string;
smallerBody: string;