mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-18 00:19:49 +01:00
MakeStyles refactor 1-5 (#2850)
ConstraintAccordion Signed-off-by: andreas-unleash <andreas@getunleash.ai> <!-- Thanks for creating a PR! To make it easier for reviewers and everyone else to understand what your changes relate to, please add some relevant content to the headings below. Feel free to ignore or delete sections that you don't think are relevant. Thank you! ❤️ --> ## About the changes <!-- Describe the changes introduced. What are they and why are they being introduced? Feel free to also add screenshots or steps to view the changes if they're visual. --> <!-- Does it close an issue? Multiple? --> Closes # <!-- (For internal contributors): Does it relate to an issue on public roadmap? --> <!-- Relates to [roadmap](https://github.com/orgs/Unleash/projects/10) item: # --> ### Important files <!-- PRs can contain a lot of changes, but not all changes are equally important. Where should a reviewer start looking to get an overview of the changes? Are any files particularly important? --> ## Discussion points <!-- Anything about the PR you'd like to discuss before it gets merged? Got any questions or doubts? --> Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
parent
9ea67a74b4
commit
186accdef7
@ -1,125 +0,0 @@
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
export const useStyles = makeStyles()(theme => ({
|
||||
constraintIconContainer: {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
borderRadius: '50%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginRight: theme.spacing(1),
|
||||
[theme.breakpoints.down(650)]: {
|
||||
marginBottom: '1rem',
|
||||
marginRight: 0,
|
||||
},
|
||||
},
|
||||
constraintIcon: {
|
||||
fill: '#fff',
|
||||
},
|
||||
accordion: {
|
||||
border: `1px solid ${theme.palette.dividerAlternative}`,
|
||||
borderRadius: theme.shape.borderRadiusMedium,
|
||||
backgroundColor: theme.palette.constraintAccordion.background,
|
||||
boxShadow: 'none',
|
||||
margin: 0,
|
||||
},
|
||||
accordionRoot: {
|
||||
'&:before': {
|
||||
opacity: '0 !important',
|
||||
},
|
||||
},
|
||||
accordionEdit: {
|
||||
backgroundColor: theme.palette.constraintAccordion.editBackground,
|
||||
},
|
||||
headerContainer: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
},
|
||||
},
|
||||
headerValues: {
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
},
|
||||
editingBadge: {
|
||||
borderRadius: theme.shape.borderRadiusExtraLarge,
|
||||
padding: '0.25rem 0.5rem',
|
||||
backgroundColor: '#635DC5',
|
||||
color: '#fff',
|
||||
marginLeft: 'auto',
|
||||
fontSize: '0.9rem',
|
||||
[theme.breakpoints.down(650)]: {
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: '-10px',
|
||||
},
|
||||
},
|
||||
headerText: {
|
||||
maxWidth: '400px',
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
[theme.breakpoints.down('xl')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
selectContainer: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
[theme.breakpoints.down(770)]: {
|
||||
flexDirection: 'column',
|
||||
},
|
||||
},
|
||||
bottomSelect: {
|
||||
[theme.breakpoints.down(770)]: {
|
||||
marginTop: '1rem',
|
||||
},
|
||||
display: 'inline-flex',
|
||||
},
|
||||
headerSelect: {
|
||||
marginRight: '1rem',
|
||||
width: '200px',
|
||||
[theme.breakpoints.between(1101, 1365)]: {
|
||||
width: '170px',
|
||||
marginRight: '8px',
|
||||
},
|
||||
},
|
||||
chip: {
|
||||
margin: '0 0.5rem 0.5rem 0',
|
||||
},
|
||||
chipValue: {
|
||||
whiteSpace: 'pre',
|
||||
},
|
||||
headerActions: {
|
||||
marginLeft: 'auto',
|
||||
whiteSpace: 'nowrap',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
accordionDetails: {
|
||||
borderTop: `1px dashed ${theme.palette.grey[300]}`,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
valuesContainer: {
|
||||
padding: '1rem 0rem',
|
||||
maxHeight: '400px',
|
||||
overflowY: 'auto',
|
||||
},
|
||||
summary: {
|
||||
border: 'none',
|
||||
padding: theme.spacing(0.5, 3),
|
||||
'&:hover .valuesExpandLabel': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
},
|
||||
settingsIcon: {
|
||||
height: '32.5px',
|
||||
width: '32.5px',
|
||||
marginRight: '0.5rem',
|
||||
fill: theme.palette.inactiveIcon,
|
||||
},
|
||||
form: { padding: 0, margin: 0, width: '100%' },
|
||||
}));
|
@ -1,10 +1,13 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { IConstraint } from 'interfaces/strategy';
|
||||
import { useStyles } from '../ConstraintAccordion.styles';
|
||||
import { ConstraintAccordionEditBody } from './ConstraintAccordionEditBody/ConstraintAccordionEditBody';
|
||||
import { ConstraintAccordionEditHeader } from './ConstraintAccordionEditHeader/ConstraintAccordionEditHeader';
|
||||
import { Accordion, AccordionDetails, AccordionSummary } from '@mui/material';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
styled,
|
||||
} from '@mui/material';
|
||||
import { cleanConstraint } from 'utils/cleanConstraint';
|
||||
import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi';
|
||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||
@ -44,6 +47,36 @@ const resolveContextDefinition = (
|
||||
);
|
||||
};
|
||||
|
||||
const StyledForm = styled('div')({ padding: 0, margin: 0, width: '100%' });
|
||||
|
||||
const StyledAccordion = styled(Accordion)(({ theme }) => ({
|
||||
border: `1px solid ${theme.palette.dividerAlternative}`,
|
||||
borderRadius: theme.shape.borderRadiusMedium,
|
||||
backgroundColor: theme.palette.constraintAccordion.editBackground,
|
||||
boxShadow: 'none',
|
||||
margin: 0,
|
||||
'& .expanded': {
|
||||
'&:before': {
|
||||
opacity: '0 !important',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
||||
border: 'none',
|
||||
padding: theme.spacing(0.5, 3),
|
||||
'&:hover .valuesExpandLabel': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
|
||||
borderTop: `1px dashed ${theme.palette.divider}`,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
padding: 0,
|
||||
}));
|
||||
|
||||
export const ConstraintAccordionEdit = ({
|
||||
constraint,
|
||||
compact,
|
||||
@ -62,7 +95,6 @@ export const ConstraintAccordionEdit = ({
|
||||
const { validateConstraint } = useFeatureApi();
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const [action, setAction] = useState('');
|
||||
const { classes: styles } = useStyles();
|
||||
|
||||
useEffect(() => {
|
||||
// Setting expanded to true on mount will cause the accordion
|
||||
@ -177,13 +209,8 @@ export const ConstraintAccordionEdit = ({
|
||||
}, [localConstraint.operator, localConstraint.contextName, setError]);
|
||||
|
||||
return (
|
||||
<div className={styles.form}>
|
||||
<Accordion
|
||||
className={classnames(styles.accordion, styles.accordionEdit)}
|
||||
classes={{
|
||||
expanded: styles.accordionRoot,
|
||||
}}
|
||||
style={{ boxShadow: 'none' }}
|
||||
<StyledForm>
|
||||
<StyledAccordion
|
||||
expanded={expanded}
|
||||
TransitionProps={{
|
||||
onExited: () => {
|
||||
@ -197,7 +224,7 @@ export const ConstraintAccordionEdit = ({
|
||||
},
|
||||
}}
|
||||
>
|
||||
<AccordionSummary className={styles.summary}>
|
||||
<StyledAccordionSummary>
|
||||
<ConstraintAccordionEditHeader
|
||||
localConstraint={localConstraint}
|
||||
setLocalConstraint={setLocalConstraint}
|
||||
@ -209,12 +236,9 @@ export const ConstraintAccordionEdit = ({
|
||||
setCaseInsensitive={setCaseInsensitive}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
</AccordionSummary>
|
||||
</StyledAccordionSummary>
|
||||
|
||||
<AccordionDetails
|
||||
className={styles.accordionDetails}
|
||||
style={{ padding: 0 }}
|
||||
>
|
||||
<StyledAccordionDetails>
|
||||
<ConstraintAccordionEditBody
|
||||
localConstraint={localConstraint}
|
||||
setValues={setValues}
|
||||
@ -234,8 +258,8 @@ export const ConstraintAccordionEdit = ({
|
||||
removeValue={removeValue}
|
||||
/>
|
||||
</ConstraintAccordionEditBody>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</div>
|
||||
</StyledAccordionDetails>
|
||||
</StyledAccordion>
|
||||
</StyledForm>
|
||||
);
|
||||
};
|
||||
|
@ -1,27 +0,0 @@
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
export const useStyles = makeStyles()(theme => ({
|
||||
inputContainer: {
|
||||
padding: '1rem',
|
||||
backgroundColor: theme.palette.neutral.light,
|
||||
},
|
||||
buttonContainer: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginTop: '1rem',
|
||||
borderTop: `1px solid ${theme.palette.grey[300]}`,
|
||||
width: '100%',
|
||||
padding: '1rem',
|
||||
},
|
||||
innerButtonContainer: {
|
||||
marginLeft: 'auto',
|
||||
},
|
||||
leftButton: {
|
||||
marginRight: '0.5rem',
|
||||
minWidth: '125px',
|
||||
},
|
||||
rightButton: {
|
||||
marginLeft: '0.5rem',
|
||||
minWidth: '125px',
|
||||
},
|
||||
}));
|
@ -1,8 +1,7 @@
|
||||
import { Button } from '@mui/material';
|
||||
import { Button, styled } from '@mui/material';
|
||||
import { IConstraint } from 'interfaces/strategy';
|
||||
import { CANCEL } from '../ConstraintAccordionEdit';
|
||||
|
||||
import { useStyles } from './ConstraintAccordionEditBody.styles';
|
||||
import React from 'react';
|
||||
import { newOperators } from 'constants/operators';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
@ -18,42 +17,66 @@ interface IConstraintAccordionBody {
|
||||
onSubmit: () => void;
|
||||
}
|
||||
|
||||
const StyledInputContainer = styled('div')(({ theme }) => ({
|
||||
padding: theme.spacing(2),
|
||||
backgroundColor: theme.palette.neutral.light,
|
||||
}));
|
||||
|
||||
const StyledButtonContainer = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginTop: theme.spacing(2),
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
width: '100%',
|
||||
padding: theme.spacing(2),
|
||||
}));
|
||||
|
||||
const StyledInputButtonContainer = styled('div')({
|
||||
marginLeft: 'auto',
|
||||
});
|
||||
|
||||
const StyledLeftButton = styled(Button)(({ theme }) => ({
|
||||
marginRight: theme.spacing(1),
|
||||
minWidth: '125px',
|
||||
}));
|
||||
|
||||
const StyledRightButton = styled(Button)(({ theme }) => ({
|
||||
marginLeft: theme.spacing(1),
|
||||
minWidth: '125px',
|
||||
}));
|
||||
|
||||
export const ConstraintAccordionEditBody: React.FC<
|
||||
IConstraintAccordionBody
|
||||
> = ({ localConstraint, children, triggerTransition, setAction, onSubmit }) => {
|
||||
const { classes: styles } = useStyles();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.inputContainer}>
|
||||
<StyledInputContainer>
|
||||
<ConditionallyRender
|
||||
condition={oneOf(newOperators, localConstraint.operator)}
|
||||
show={<OperatorUpgradeAlert />}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
<div className={styles.buttonContainer}>
|
||||
<div className={styles.innerButtonContainer}>
|
||||
<Button
|
||||
</StyledInputContainer>
|
||||
<StyledButtonContainer>
|
||||
<StyledInputButtonContainer>
|
||||
<StyledLeftButton
|
||||
type="button"
|
||||
onClick={onSubmit}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={styles.leftButton}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
<Button
|
||||
</StyledLeftButton>
|
||||
<StyledRightButton
|
||||
onClick={() => {
|
||||
setAction(CANCEL);
|
||||
triggerTransition();
|
||||
}}
|
||||
className={styles.rightButton}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</StyledRightButton>
|
||||
</StyledInputButtonContainer>
|
||||
</StyledButtonContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { IConstraint } from 'interfaces/strategy';
|
||||
|
||||
import { useStyles } from 'component/common/ConstraintAccordion/ConstraintAccordion.styles';
|
||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||
import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect';
|
||||
import { ConstraintIcon } from 'component/common/ConstraintAccordion/ConstraintIcon';
|
||||
@ -23,6 +22,7 @@ import {
|
||||
import { InvertedOperatorButton } from '../StyledToggleButton/InvertedOperatorButton/InvertedOperatorButton';
|
||||
import { CaseSensitiveButton } from '../StyledToggleButton/CaseSensitiveButton/CaseSensitiveButton';
|
||||
import { ConstraintAccordionHeaderActions } from '../../ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions';
|
||||
import { styled } from '@mui/material';
|
||||
|
||||
interface IConstraintAccordionViewHeader {
|
||||
localConstraint: IConstraint;
|
||||
@ -36,6 +36,56 @@ interface IConstraintAccordionViewHeader {
|
||||
setCaseInsensitive: () => void;
|
||||
}
|
||||
|
||||
const StyledHeaderContainer = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
},
|
||||
}));
|
||||
const StyledSelectContainer = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
[theme.breakpoints.down(770)]: {
|
||||
flexDirection: 'column',
|
||||
},
|
||||
}));
|
||||
const StyledBottomSelect = styled('div')(({ theme }) => ({
|
||||
[theme.breakpoints.down(770)]: {
|
||||
marginTop: theme.spacing(2),
|
||||
},
|
||||
display: 'inline-flex',
|
||||
}));
|
||||
|
||||
const StyledHeaderSelect = styled('div')(({ theme }) => ({
|
||||
marginRight: theme.spacing(2),
|
||||
width: '200px',
|
||||
[theme.breakpoints.between(1101, 1365)]: {
|
||||
width: '170px',
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledGeneralSelect = styled(GeneralSelect)(({ theme }) => ({
|
||||
marginRight: theme.spacing(2),
|
||||
width: '200px',
|
||||
[theme.breakpoints.between(1101, 1365)]: {
|
||||
width: '170px',
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledHeaderText = styled('p')(({ theme }) => ({
|
||||
maxWidth: '400px',
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
[theme.breakpoints.down('xl')]: {
|
||||
display: 'none',
|
||||
},
|
||||
}));
|
||||
|
||||
export const ConstraintAccordionEditHeader = ({
|
||||
compact,
|
||||
localConstraint,
|
||||
@ -46,7 +96,6 @@ export const ConstraintAccordionEditHeader = ({
|
||||
setInvertedOperator,
|
||||
setCaseInsensitive,
|
||||
}: IConstraintAccordionViewHeader) => {
|
||||
const { classes: styles } = useStyles();
|
||||
const { context } = useUnleashContext();
|
||||
const { contextName, operator } = localConstraint;
|
||||
const [showCaseSensitiveButton, setShowCaseSensitiveButton] =
|
||||
@ -108,11 +157,11 @@ export const ConstraintAccordionEditHeader = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.headerContainer}>
|
||||
<StyledHeaderContainer>
|
||||
<ConstraintIcon />
|
||||
<div className={styles.selectContainer}>
|
||||
<StyledSelectContainer>
|
||||
<div>
|
||||
<GeneralSelect
|
||||
<StyledGeneralSelect
|
||||
id="context-field-select"
|
||||
name="contextName"
|
||||
label="Context Field"
|
||||
@ -120,21 +169,20 @@ export const ConstraintAccordionEditHeader = ({
|
||||
options={constraintNameOptions}
|
||||
value={contextName || ''}
|
||||
onChange={setContextName}
|
||||
className={styles.headerSelect}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.bottomSelect}>
|
||||
<StyledBottomSelect>
|
||||
<InvertedOperatorButton
|
||||
localConstraint={localConstraint}
|
||||
setInvertedOperator={setInvertedOperator}
|
||||
/>
|
||||
<div className={styles.headerSelect}>
|
||||
<StyledHeaderSelect>
|
||||
<ConstraintOperatorSelect
|
||||
options={operatorsForContext(contextName)}
|
||||
value={operator}
|
||||
onChange={onOperatorChange}
|
||||
/>
|
||||
</div>
|
||||
</StyledHeaderSelect>
|
||||
<ConditionallyRender
|
||||
condition={showCaseSensitiveButton}
|
||||
show={
|
||||
@ -144,17 +192,17 @@ export const ConstraintAccordionEditHeader = ({
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</StyledBottomSelect>
|
||||
</StyledSelectContainer>
|
||||
<ConditionallyRender
|
||||
condition={!compact}
|
||||
show={
|
||||
<p className={styles.headerText}>
|
||||
<StyledHeaderText>
|
||||
{resolveText(operator, contextName)}
|
||||
</p>
|
||||
</StyledHeaderText>
|
||||
}
|
||||
/>
|
||||
<ConstraintAccordionHeaderActions onDelete={onDelete} disableEdit />
|
||||
</div>
|
||||
</StyledHeaderContainer>
|
||||
);
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { IconButton, Tooltip } from '@mui/material';
|
||||
import { IconButton, styled, Tooltip } from '@mui/material';
|
||||
import { Delete, Edit } from '@mui/icons-material';
|
||||
import { useStyles } from '../ConstraintAccordion.styles';
|
||||
import { ConditionallyRender } from '../../ConditionallyRender/ConditionallyRender';
|
||||
|
||||
interface ConstraintAccordionHeaderActionsProps {
|
||||
@ -11,13 +10,20 @@ interface ConstraintAccordionHeaderActionsProps {
|
||||
disableDelete?: boolean;
|
||||
}
|
||||
|
||||
const StyledHeaderActions = styled('div')(({ theme }) => ({
|
||||
marginLeft: 'auto',
|
||||
whiteSpace: 'nowrap',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
display: 'none',
|
||||
},
|
||||
}));
|
||||
|
||||
export const ConstraintAccordionHeaderActions = ({
|
||||
onEdit,
|
||||
onDelete,
|
||||
disableDelete = false,
|
||||
disableEdit = false,
|
||||
}: ConstraintAccordionHeaderActionsProps) => {
|
||||
const { classes: styles } = useStyles();
|
||||
const onEditClick =
|
||||
onEdit &&
|
||||
((event: React.SyntheticEvent) => {
|
||||
@ -33,7 +39,7 @@ export const ConstraintAccordionHeaderActions = ({
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={styles.headerActions}>
|
||||
<StyledHeaderActions>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(onEditClick) && !disableEdit}
|
||||
show={
|
||||
@ -62,6 +68,6 @@ export const ConstraintAccordionHeaderActions = ({
|
||||
</Tooltip>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</StyledHeaderActions>
|
||||
);
|
||||
};
|
||||
|
@ -1,29 +0,0 @@
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
export const useStyles = makeStyles()(theme => ({
|
||||
container: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
help: {
|
||||
fill: theme.palette.grey[600],
|
||||
[theme.breakpoints.down(860)]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
helpWrapper: {
|
||||
marginLeft: '12px',
|
||||
height: '24px',
|
||||
},
|
||||
addCustomLabel: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'start',
|
||||
margin: '0.75rem 0 ',
|
||||
},
|
||||
customConstraintLabel: {
|
||||
marginBottom: theme.spacing(1),
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
}));
|
@ -1,5 +1,5 @@
|
||||
import React, { forwardRef, Fragment, useImperativeHandle } from 'react';
|
||||
import { Button, Tooltip } from '@mui/material';
|
||||
import { Button, styled, Tooltip } from '@mui/material';
|
||||
import { HelpOutline } from '@mui/icons-material';
|
||||
import { IConstraint } from 'interfaces/strategy';
|
||||
import { ConstraintAccordion } from 'component/common/ConstraintAccordion/ConstraintAccordion';
|
||||
@ -7,7 +7,6 @@ import produce from 'immer';
|
||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||
import { useWeakMap } from 'hooks/useWeakMap';
|
||||
import { objectId } from 'utils/objectId';
|
||||
import { useStyles } from './ConstraintAccordionList.styles';
|
||||
import { createEmptyConstraint } from 'component/common/ConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
||||
@ -35,6 +34,34 @@ interface IConstraintAccordionListItemState {
|
||||
|
||||
export const constraintAccordionListId = 'constraintAccordionListId';
|
||||
|
||||
const StyledContainer = styled('div')({
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
});
|
||||
|
||||
const StyledHelpWrapper = styled(Tooltip)(({ theme }) => ({
|
||||
marginLeft: theme.spacing(0.75),
|
||||
height: theme.spacing(1.5),
|
||||
}));
|
||||
|
||||
const StyledHelp = styled(HelpOutline)(({ theme }) => ({
|
||||
fill: theme.palette.tertiary.dark,
|
||||
[theme.breakpoints.down(860)]: {
|
||||
display: 'none',
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledConstraintLabel = styled('p')(({ theme }) => ({
|
||||
marginBottom: theme.spacing(1),
|
||||
color: theme.palette.text.secondary,
|
||||
}));
|
||||
|
||||
const StyledAddCustomLabel = styled('div')(({ theme }) => ({
|
||||
marginBottom: theme.spacing(1),
|
||||
color: theme.palette.text.secondary,
|
||||
}));
|
||||
|
||||
export const ConstraintAccordionList = forwardRef<
|
||||
IConstraintAccordionListRef | undefined,
|
||||
IConstraintAccordionListProps
|
||||
@ -48,7 +75,6 @@ export const ConstraintAccordionList = forwardRef<
|
||||
IConstraintAccordionListItemState
|
||||
>();
|
||||
const { context } = useUnleashContext();
|
||||
const { classes: styles } = useStyles();
|
||||
|
||||
const addConstraint =
|
||||
setConstraints &&
|
||||
@ -108,15 +134,15 @@ export const ConstraintAccordionList = forwardRef<
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.container} id={constraintAccordionListId}>
|
||||
<StyledContainer id={constraintAccordionListId}>
|
||||
<ConditionallyRender
|
||||
condition={
|
||||
constraints && constraints.length > 0 && showLabel
|
||||
}
|
||||
show={
|
||||
<p className={styles.customConstraintLabel}>
|
||||
<StyledConstraintLabel>
|
||||
Constraints
|
||||
</p>
|
||||
</StyledConstraintLabel>
|
||||
}
|
||||
/>
|
||||
{constraints.map((constraint, index) => (
|
||||
@ -140,13 +166,9 @@ export const ConstraintAccordionList = forwardRef<
|
||||
condition={Boolean(showCreateButton && onAdd)}
|
||||
show={
|
||||
<div>
|
||||
<div className={styles.addCustomLabel}>
|
||||
<StyledAddCustomLabel>
|
||||
<p>Add any number of constraints</p>
|
||||
<Tooltip
|
||||
title="Help"
|
||||
arrow
|
||||
className={styles.helpWrapper}
|
||||
>
|
||||
<StyledHelpWrapper title="Help" arrow>
|
||||
<a
|
||||
href={
|
||||
'https://docs.getunleash.io/reference/strategy-constraints'
|
||||
@ -154,10 +176,10 @@ export const ConstraintAccordionList = forwardRef<
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<HelpOutline className={styles.help} />
|
||||
<StyledHelp />
|
||||
</a>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</StyledHelpWrapper>
|
||||
</StyledAddCustomLabel>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={onAdd}
|
||||
@ -169,7 +191,7 @@ export const ConstraintAccordionList = forwardRef<
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
AccordionDetails,
|
||||
SxProps,
|
||||
Theme,
|
||||
styled,
|
||||
} from '@mui/material';
|
||||
import { IConstraint } from 'interfaces/strategy';
|
||||
import { ConstraintAccordionViewBody } from './ConstraintAccordionViewBody/ConstraintAccordionViewBody';
|
||||
@ -15,7 +16,6 @@ import {
|
||||
numOperators,
|
||||
semVerOperators,
|
||||
} from 'constants/operators';
|
||||
import { useStyles } from '../ConstraintAccordion.styles';
|
||||
|
||||
interface IConstraintAccordionViewProps {
|
||||
constraint: IConstraint;
|
||||
@ -26,6 +26,41 @@ interface IConstraintAccordionViewProps {
|
||||
renderAfter?: JSX.Element;
|
||||
}
|
||||
|
||||
const StyledAccordion = styled(Accordion)(({ theme }) => ({
|
||||
border: `1px solid ${theme.palette.dividerAlternative}`,
|
||||
borderRadius: theme.shape.borderRadiusMedium,
|
||||
backgroundColor: theme.palette.constraintAccordion.background,
|
||||
boxShadow: 'none',
|
||||
margin: 0,
|
||||
|
||||
'& .root': {
|
||||
'&:before': {
|
||||
opacity: '0 !important',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
||||
'& .root': {
|
||||
border: 'none',
|
||||
padding: theme.spacing(0.5, 3),
|
||||
'&:hover .valuesExpandLabel': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
},
|
||||
}));
|
||||
const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
|
||||
borderTop: `1px dashed ${theme.palette.divider}`,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}));
|
||||
|
||||
const StyledWrapper = styled('div')({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
export const ConstraintAccordionView = ({
|
||||
constraint,
|
||||
onEdit,
|
||||
@ -34,7 +69,6 @@ export const ConstraintAccordionView = ({
|
||||
compact = false,
|
||||
renderAfter,
|
||||
}: IConstraintAccordionViewProps) => {
|
||||
const { classes: styles } = useStyles();
|
||||
const [expandable, setExpandable] = useState(true);
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
|
||||
@ -49,14 +83,8 @@ export const ConstraintAccordionView = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Accordion
|
||||
className={styles.accordion}
|
||||
classes={{ root: styles.accordionRoot }}
|
||||
expanded={expanded}
|
||||
sx={sx}
|
||||
>
|
||||
<AccordionSummary
|
||||
classes={{ root: styles.summary }}
|
||||
<StyledAccordion expanded={expanded} sx={sx}>
|
||||
<StyledAccordionSummary
|
||||
expandIcon={null}
|
||||
onClick={handleClick}
|
||||
sx={{
|
||||
@ -66,13 +94,7 @@ export const ConstraintAccordionView = ({
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<StyledWrapper>
|
||||
<ConstraintAccordionViewHeader
|
||||
constraint={constraint}
|
||||
onEdit={onEdit}
|
||||
@ -83,12 +105,12 @@ export const ConstraintAccordionView = ({
|
||||
compact={compact}
|
||||
/>
|
||||
{renderAfter}
|
||||
</div>
|
||||
</AccordionSummary>
|
||||
</StyledWrapper>
|
||||
</StyledAccordionSummary>
|
||||
|
||||
<AccordionDetails className={styles.accordionDetails}>
|
||||
<StyledAccordionDetails>
|
||||
<ConstraintAccordionViewBody constraint={constraint} />
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</StyledAccordionDetails>
|
||||
</StyledAccordion>
|
||||
);
|
||||
};
|
||||
|
@ -1,27 +0,0 @@
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
export const useStyles = makeStyles()(theme => ({
|
||||
chip: {
|
||||
margin: '0 0.5rem 0.5rem 0',
|
||||
},
|
||||
chipValue: {
|
||||
whiteSpace: 'pre',
|
||||
},
|
||||
singleValueView: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
[theme.breakpoints.down(600)]: { flexDirection: 'column' },
|
||||
},
|
||||
singleValueText: {
|
||||
marginRight: '0.75rem',
|
||||
[theme.breakpoints.down(600)]: {
|
||||
marginBottom: '0.75rem',
|
||||
marginRight: 0,
|
||||
},
|
||||
},
|
||||
settingsParagraph: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '0.5rem 0',
|
||||
},
|
||||
}));
|
@ -1,29 +1,34 @@
|
||||
import { IConstraint } from 'interfaces/strategy';
|
||||
import { useStyles } from 'component/common/ConstraintAccordion/ConstraintAccordion.styles';
|
||||
import { formatConstraintValue } from 'utils/formatConstraintValue';
|
||||
import { useLocationSettings } from 'hooks/useLocationSettings';
|
||||
import { MultipleValues } from './MultipleValues/MultipleValues';
|
||||
import { SingleValue } from './SingleValue/SingleValue';
|
||||
import { styled } from '@mui/material';
|
||||
|
||||
interface IConstraintAccordionViewBodyProps {
|
||||
constraint: IConstraint;
|
||||
}
|
||||
|
||||
const StyledValueContainer = styled('div')(({ theme }) => ({
|
||||
padding: theme.spacing(2, 0),
|
||||
maxHeight: '400px',
|
||||
overflowY: 'auto',
|
||||
}));
|
||||
|
||||
export const ConstraintAccordionViewBody = ({
|
||||
constraint,
|
||||
}: IConstraintAccordionViewBodyProps) => {
|
||||
const { classes: styles } = useStyles();
|
||||
const { locationSettings } = useLocationSettings();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.valuesContainer}>
|
||||
<StyledValueContainer>
|
||||
<MultipleValues values={constraint.values} />
|
||||
<SingleValue
|
||||
value={formatConstraintValue(constraint, locationSettings)}
|
||||
operator={constraint.operator}
|
||||
/>
|
||||
</div>
|
||||
</StyledValueContainer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +1,23 @@
|
||||
import { useState } from 'react';
|
||||
import { Chip } from '@mui/material';
|
||||
import { Chip, styled } from '@mui/material';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
||||
import { ConstraintValueSearch } from '../../../ConstraintValueSearch/ConstraintValueSearch';
|
||||
import { useStyles } from '../ConstraintAccordionViewBody.style';
|
||||
|
||||
interface IMultipleValuesProps {
|
||||
values: string[] | undefined;
|
||||
}
|
||||
|
||||
const StyledTruncator = styled(StringTruncator)({
|
||||
whiteSpace: 'pre',
|
||||
});
|
||||
|
||||
const StyledChip = styled(Chip)(({ theme }) => ({
|
||||
margin: theme.spacing(0, 1, 1, 0),
|
||||
}));
|
||||
|
||||
export const MultipleValues = ({ values }: IMultipleValuesProps) => {
|
||||
const [filter, setFilter] = useState('');
|
||||
const { classes: styles } = useStyles();
|
||||
|
||||
if (!values || values.length === 0) return null;
|
||||
|
||||
@ -29,17 +35,15 @@ export const MultipleValues = ({ values }: IMultipleValuesProps) => {
|
||||
{values
|
||||
.filter(value => value.includes(filter))
|
||||
.map((value, index) => (
|
||||
<Chip
|
||||
<StyledChip
|
||||
key={`${value}-${index}`}
|
||||
label={
|
||||
<StringTruncator
|
||||
<StyledTruncator
|
||||
maxWidth="400"
|
||||
text={value}
|
||||
maxLength={50}
|
||||
className={styles.chipValue}
|
||||
/>
|
||||
}
|
||||
className={styles.chip}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
|
@ -2,7 +2,7 @@ import { ConstraintIcon } from 'component/common/ConstraintAccordion/ConstraintI
|
||||
import { IConstraint } from 'interfaces/strategy';
|
||||
import { ConstraintAccordionViewHeaderInfo } from './ConstraintAccordionViewHeaderInfo';
|
||||
import { ConstraintAccordionHeaderActions } from '../../ConstraintAccordionHeaderActions/ConstraintAccordionHeaderActions';
|
||||
import { useStyles } from 'component/common/ConstraintAccordion/ConstraintAccordion.styles';
|
||||
import { styled } from '@mui/system';
|
||||
|
||||
interface IConstraintAccordionViewHeaderProps {
|
||||
constraint: IConstraint;
|
||||
@ -14,6 +14,17 @@ interface IConstraintAccordionViewHeaderProps {
|
||||
compact?: boolean;
|
||||
}
|
||||
|
||||
const StyledContainer = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
},
|
||||
}));
|
||||
|
||||
export const ConstraintAccordionViewHeader = ({
|
||||
constraint,
|
||||
onEdit,
|
||||
@ -23,10 +34,8 @@ export const ConstraintAccordionViewHeader = ({
|
||||
expanded,
|
||||
compact,
|
||||
}: IConstraintAccordionViewHeaderProps) => {
|
||||
const { classes: styles } = useStyles();
|
||||
|
||||
return (
|
||||
<div className={styles.headerContainer}>
|
||||
<StyledContainer>
|
||||
<ConstraintIcon compact={compact} />
|
||||
<ConstraintAccordionViewHeaderInfo
|
||||
constraint={constraint}
|
||||
@ -38,6 +47,6 @@ export const ConstraintAccordionViewHeader = ({
|
||||
onEdit={onEdit}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
</div>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user