mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-18 00:19:49 +01:00
Fix/minor 41 bugs (#329)
* fix: bigger buttons * feat: dialogue on strategies * fix: constraint errors * fix: add constraint button * fix: variant dialogue size * fix: remove commented code * fix: remove unused imports * fix: change xs to int * fix: verify constraint config before saving strategy * fix: reset error when context field is removed * fix: preserve previous state when updating * fix: disable lint for useEffect * fix: update snapshots
This commit is contained in:
parent
c33581081b
commit
e0f7a78833
@ -16,6 +16,7 @@ body {
|
|||||||
.MuiButton-root {
|
.MuiButton-root {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skeleton {
|
.skeleton {
|
||||||
|
@ -16,8 +16,11 @@ const Dialogue = ({
|
|||||||
onClick,
|
onClick,
|
||||||
onClose,
|
onClose,
|
||||||
title,
|
title,
|
||||||
|
style,
|
||||||
primaryButtonText,
|
primaryButtonText,
|
||||||
|
disabledPrimaryButton = false,
|
||||||
secondaryButtonText,
|
secondaryButtonText,
|
||||||
|
maxWidth = 'sm',
|
||||||
fullWidth = false,
|
fullWidth = false,
|
||||||
}) => {
|
}) => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
@ -28,6 +31,7 @@ const Dialogue = ({
|
|||||||
fullWidth={fullWidth}
|
fullWidth={fullWidth}
|
||||||
aria-labelledby={'simple-modal-title'}
|
aria-labelledby={'simple-modal-title'}
|
||||||
aria-describedby={'simple-modal-description'}
|
aria-describedby={'simple-modal-description'}
|
||||||
|
maxWidth={maxWidth}
|
||||||
>
|
>
|
||||||
<DialogTitle className={styles.dialogTitle}>{title}</DialogTitle>
|
<DialogTitle className={styles.dialogTitle}>{title}</DialogTitle>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
@ -48,6 +52,7 @@ const Dialogue = ({
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
autoFocus
|
autoFocus
|
||||||
|
disabled={disabledPrimaryButton}
|
||||||
>
|
>
|
||||||
{primaryButtonText || "Yes, I'm sure"}
|
{primaryButtonText || "Yes, I'm sure"}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -84,7 +84,7 @@ const FeatureToggleListNew = ({
|
|||||||
)}
|
)}
|
||||||
align="left"
|
align="left"
|
||||||
>
|
>
|
||||||
<span data-loading>name</span>
|
<span data-loading>Name</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell
|
<TableCell
|
||||||
className={classnames(
|
className={classnames(
|
||||||
@ -94,7 +94,7 @@ const FeatureToggleListNew = ({
|
|||||||
)}
|
)}
|
||||||
align="left"
|
align="left"
|
||||||
>
|
>
|
||||||
<span data-loading>type</span>
|
<span data-loading>Type</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
{getEnvironments().map((env: any) => {
|
{getEnvironments().map((env: any) => {
|
||||||
return (
|
return (
|
||||||
@ -109,7 +109,7 @@ const FeatureToggleListNew = ({
|
|||||||
>
|
>
|
||||||
<span data-loading>
|
<span data-loading>
|
||||||
{env.name === ':global:'
|
{env.name === ':global:'
|
||||||
? 'status'
|
? 'Status'
|
||||||
: env.name}
|
: env.name}
|
||||||
</span>
|
</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {
|
import { Typography } from '@material-ui/core';
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogTitle,
|
|
||||||
DialogActions,
|
|
||||||
Typography,
|
|
||||||
} from '@material-ui/core';
|
|
||||||
|
|
||||||
import CreateStrategyCard from './AddStrategyCard/AddStrategyCard';
|
import CreateStrategyCard from './AddStrategyCard/AddStrategyCard';
|
||||||
import { useStyles } from './AddStrategy.styles';
|
import { useStyles } from './AddStrategy.styles';
|
||||||
import ConditionallyRender from '../../../common/ConditionallyRender';
|
import ConditionallyRender from '../../../common/ConditionallyRender';
|
||||||
import { resolveDefaultParamValue } from './utils';
|
import { resolveDefaultParamValue } from './utils';
|
||||||
import { getHumanReadbleStrategy } from '../../../../utils/strategy-names';
|
import { getHumanReadbleStrategy } from '../../../../utils/strategy-names';
|
||||||
|
import Dialogue from '../../../common/Dialogue';
|
||||||
|
|
||||||
const AddStrategy = ({
|
const AddStrategy = ({
|
||||||
strategies,
|
strategies,
|
||||||
@ -98,49 +91,39 @@ const AddStrategy = ({
|
|||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialogue
|
||||||
open={showCreateStrategy}
|
open={showCreateStrategy}
|
||||||
|
title="Add a new strategy"
|
||||||
aria-labelledby="form-dialog-title"
|
aria-labelledby="form-dialog-title"
|
||||||
fullWidth
|
onClose={() => setShowCreateStrategy(false)}
|
||||||
|
secondaryButtonText="Cancel"
|
||||||
maxWidth="md"
|
maxWidth="md"
|
||||||
|
fullWidth
|
||||||
>
|
>
|
||||||
<DialogTitle id="form-dialog-title">Add a new strategy</DialogTitle>
|
<Typography variant="subtitle1" className={styles.subTitle}>
|
||||||
|
Built in strategies
|
||||||
|
</Typography>
|
||||||
|
<div className={styles.createStrategyCardContainer}>
|
||||||
|
{renderBuiltInStrategies()}
|
||||||
|
</div>
|
||||||
|
|
||||||
<DialogContent>
|
<ConditionallyRender
|
||||||
<Typography variant="subtitle1" className={styles.subTitle}>
|
condition={customStrategies.length > 0}
|
||||||
Built in strategies
|
show={
|
||||||
</Typography>
|
<>
|
||||||
<div className={styles.createStrategyCardContainer}>
|
<Typography
|
||||||
{renderBuiltInStrategies()}
|
variant="subtitle1"
|
||||||
</div>
|
className={styles.subTitle}
|
||||||
|
>
|
||||||
<ConditionallyRender
|
Custom strategies
|
||||||
condition={customStrategies.length > 0}
|
</Typography>
|
||||||
show={
|
<div className={styles.createStrategyCardContainer}>
|
||||||
<>
|
{renderCustomStrategies()}
|
||||||
<Typography
|
</div>
|
||||||
variant="subtitle1"
|
</>
|
||||||
className={styles.subTitle}
|
}
|
||||||
>
|
/>
|
||||||
Custom strategies
|
</Dialogue>
|
||||||
</Typography>
|
|
||||||
<div className={styles.createStrategyCardContainer}>
|
|
||||||
{renderCustomStrategies()}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</DialogContent>
|
|
||||||
|
|
||||||
<DialogActions>
|
|
||||||
<Button
|
|
||||||
color="secondary"
|
|
||||||
onClick={() => setShowCreateStrategy(false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
import React from 'react';
|
import { useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogTitle,
|
|
||||||
DialogActions,
|
|
||||||
} from '@material-ui/core';
|
|
||||||
|
|
||||||
import FlexibleStrategy from './FlexibleStrategy';
|
import FlexibleStrategy from './FlexibleStrategy';
|
||||||
import DefaultStrategy from './default-strategy';
|
import DefaultStrategy from './default-strategy';
|
||||||
@ -15,6 +8,7 @@ import GeneralStrategy from './general-strategy';
|
|||||||
import StrategyConstraints from '../StrategyConstraint/StrategyConstraintInput';
|
import StrategyConstraints from '../StrategyConstraint/StrategyConstraintInput';
|
||||||
|
|
||||||
import { getHumanReadbleStrategyName } from '../../../../utils/strategy-names';
|
import { getHumanReadbleStrategyName } from '../../../../utils/strategy-names';
|
||||||
|
import Dialogue from '../../../common/Dialogue';
|
||||||
|
|
||||||
const EditStrategyModal = ({
|
const EditStrategyModal = ({
|
||||||
onCancel,
|
onCancel,
|
||||||
@ -24,6 +18,8 @@ const EditStrategyModal = ({
|
|||||||
strategyDefinition,
|
strategyDefinition,
|
||||||
context,
|
context,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [constraintError, setConstraintError] = useState({});
|
||||||
|
|
||||||
const updateParameters = parameters => {
|
const updateParameters = parameters => {
|
||||||
const updatedStrategy = { ...strategy, parameters };
|
const updatedStrategy = { ...strategy, parameters };
|
||||||
updateStrategy(updatedStrategy);
|
updateStrategy(updatedStrategy);
|
||||||
@ -57,47 +53,66 @@ const EditStrategyModal = ({
|
|||||||
|
|
||||||
const { parameters } = strategy;
|
const { parameters } = strategy;
|
||||||
|
|
||||||
|
const disabledPrimaryButton = Object.keys(constraintError).some(key => {
|
||||||
|
return constraintError[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
const { constraints } = strategy;
|
||||||
|
let valid = true;
|
||||||
|
|
||||||
|
constraints.forEach((constraint, index) => {
|
||||||
|
const { values } = constraint;
|
||||||
|
|
||||||
|
if (values.length === 0) {
|
||||||
|
setConstraintError(prev => ({
|
||||||
|
...prev,
|
||||||
|
[`${constraint.contextName}-${index}`]:
|
||||||
|
'You need to specify at least one value',
|
||||||
|
}));
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
saveStrategy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialogue
|
||||||
open={!!strategy}
|
open={!!strategy}
|
||||||
aria-labelledby="form-dialog-title"
|
aria-labelledby="form-dialog-title"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
onClose={onCancel}
|
||||||
|
onClick={save}
|
||||||
|
title={`Configure ${getHumanReadbleStrategyName(
|
||||||
|
strategy.name
|
||||||
|
)} strategy`}
|
||||||
|
primaryButtonText="Save"
|
||||||
|
secondaryButtonText="Cancel"
|
||||||
maxWidth="md"
|
maxWidth="md"
|
||||||
|
disabledPrimaryButton={disabledPrimaryButton}
|
||||||
>
|
>
|
||||||
<DialogTitle id="form-dialog-title">
|
<div>
|
||||||
Configure {getHumanReadbleStrategyName(strategy.name)} strategy
|
<StrategyConstraints
|
||||||
</DialogTitle>
|
updateConstraints={updateConstraints}
|
||||||
<DialogContent>
|
constraints={strategy.constraints || []}
|
||||||
<div>
|
constraintError={constraintError}
|
||||||
<StrategyConstraints
|
setConstraintError={setConstraintError}
|
||||||
updateConstraints={updateConstraints}
|
|
||||||
constraints={strategy.constraints || []}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<Type
|
|
||||||
parameters={parameters}
|
|
||||||
updateParameter={updateParameter}
|
|
||||||
strategyDefinition={strategyDefinition}
|
|
||||||
editable
|
|
||||||
context={context}
|
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</div>
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={onCancel} color="secondary">
|
<br />
|
||||||
Cancel
|
<br />
|
||||||
</Button>
|
<Type
|
||||||
<Button
|
parameters={parameters}
|
||||||
onClick={saveStrategy}
|
updateParameter={updateParameter}
|
||||||
color="primary"
|
strategyDefinition={strategyDefinition}
|
||||||
variant="contained"
|
editable
|
||||||
>
|
context={context}
|
||||||
Save
|
/>
|
||||||
</Button>
|
</Dialogue>
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Tooltip, Typography } from '@material-ui/core';
|
import { Button, Tooltip, Typography } from '@material-ui/core';
|
||||||
import { Info } from '@material-ui/icons';
|
import { Info } from '@material-ui/icons';
|
||||||
|
|
||||||
import StrategyConstraintInputField from '../StrategyConstraintInputField';
|
import StrategyConstraintInputField from '../StrategyConstraintInputField';
|
||||||
@ -12,6 +12,8 @@ const StrategyConstraintInput = ({
|
|||||||
contextNames,
|
contextNames,
|
||||||
contextFields,
|
contextFields,
|
||||||
enabled,
|
enabled,
|
||||||
|
constraintError,
|
||||||
|
setConstraintError,
|
||||||
}) => {
|
}) => {
|
||||||
const commonStyles = useCommonStyles();
|
const commonStyles = useCommonStyles();
|
||||||
const addConstraint = evt => {
|
const addConstraint = evt => {
|
||||||
@ -71,18 +73,21 @@ const StrategyConstraintInput = ({
|
|||||||
contextFields={contextFields}
|
contextFields={contextFields}
|
||||||
updateConstraint={updateConstraint(index)}
|
updateConstraint={updateConstraint(index)}
|
||||||
removeConstraint={removeConstraint(index)}
|
removeConstraint={removeConstraint(index)}
|
||||||
|
constraintError={constraintError}
|
||||||
|
setConstraintError={setConstraintError}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<small>
|
<small>
|
||||||
<a
|
<Button
|
||||||
href="#add-constraint"
|
|
||||||
title="Add constraint"
|
title="Add constraint"
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
onClick={addConstraint}
|
onClick={addConstraint}
|
||||||
>
|
>
|
||||||
Add constraint
|
Add constraint
|
||||||
</a>
|
</Button>
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import { useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { IconButton, TextField } from '@material-ui/core';
|
import { IconButton, TextField } from '@material-ui/core';
|
||||||
import { Autocomplete } from '@material-ui/lab';
|
import { Autocomplete } from '@material-ui/lab';
|
||||||
@ -20,27 +20,47 @@ const StrategyConstraintInputField = ({
|
|||||||
updateConstraint,
|
updateConstraint,
|
||||||
removeConstraint,
|
removeConstraint,
|
||||||
contextFields,
|
contextFields,
|
||||||
|
id,
|
||||||
|
constraintError,
|
||||||
|
setConstraintError,
|
||||||
}) => {
|
}) => {
|
||||||
const [error, setError] = useState();
|
useEffect(() => {
|
||||||
const commonStyles = useCommonStyles();
|
return () => {
|
||||||
const styles = useStyles();
|
resetError();
|
||||||
const onBlur = evt => {
|
};
|
||||||
evt.preventDefault();
|
/*eslint-disable-next-line */
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const checkError = () => {
|
||||||
const values = constraint.values;
|
const values = constraint.values;
|
||||||
const filtered = values.filter(v => v).map(v => v.trim());
|
const filtered = values.filter(v => v).map(v => v.trim());
|
||||||
if (filtered.length !== values.length) {
|
if (filtered.length !== values.length) {
|
||||||
updateConstraint(filtered, 'values');
|
updateConstraint(filtered, 'values');
|
||||||
}
|
}
|
||||||
if (filtered.length === 0) {
|
if (filtered.length === 0) {
|
||||||
setError('You need to specify at least one value');
|
setConstraintError(prev => ({
|
||||||
|
...prev,
|
||||||
|
[id]: 'You need to specify at least one value',
|
||||||
|
}));
|
||||||
} else {
|
} else {
|
||||||
setError(undefined);
|
resetError();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resetError = () =>
|
||||||
|
setConstraintError(prev => ({ ...prev, [id]: undefined }));
|
||||||
|
|
||||||
|
const commonStyles = useCommonStyles();
|
||||||
|
const styles = useStyles();
|
||||||
|
const onBlur = evt => {
|
||||||
|
evt.preventDefault();
|
||||||
|
checkError();
|
||||||
|
};
|
||||||
|
|
||||||
const handleChangeValue = selectedOptions => {
|
const handleChangeValue = selectedOptions => {
|
||||||
const values = selectedOptions ? selectedOptions.map(o => o.value) : [];
|
const values = selectedOptions ? selectedOptions.map(o => o.value) : [];
|
||||||
updateConstraint(values, 'values');
|
updateConstraint(values, 'values');
|
||||||
|
checkError();
|
||||||
};
|
};
|
||||||
|
|
||||||
const constraintContextNames = contextFields.map(f => ({
|
const constraintContextNames = contextFields.map(f => ({
|
||||||
@ -59,9 +79,11 @@ const StrategyConstraintInputField = ({
|
|||||||
: undefined;
|
: undefined;
|
||||||
const values = constraint.values.map(v => ({ value: v, label: v }));
|
const values = constraint.values.map(v => ({ value: v, label: v }));
|
||||||
|
|
||||||
|
const error = constraintError[id];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr className={commonStyles.contentSpacingY}>
|
<tr className={commonStyles.contentSpacingY}>
|
||||||
<td>
|
<td className={styles.tableCell}>
|
||||||
<MySelect
|
<MySelect
|
||||||
name="contextName"
|
name="contextName"
|
||||||
label="Context Field"
|
label="Context Field"
|
||||||
@ -73,7 +95,7 @@ const StrategyConstraintInputField = ({
|
|||||||
className={styles.contextField}
|
className={styles.contextField}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td className={styles.tableCell}>
|
||||||
<MySelect
|
<MySelect
|
||||||
name="operator"
|
name="operator"
|
||||||
label="Operator"
|
label="Operator"
|
||||||
@ -85,52 +107,74 @@ const StrategyConstraintInputField = ({
|
|||||||
className={styles.operator}
|
className={styles.operator}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td style={{ width: '100%' }}>
|
<td className={styles.tableCell} style={{ width: '100%' }}>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={options}
|
condition={options}
|
||||||
show={
|
show={
|
||||||
<Autocomplete
|
<div className={styles.inputContainer}>
|
||||||
multiple
|
<Autocomplete
|
||||||
size="small"
|
multiple
|
||||||
options={options}
|
size="small"
|
||||||
value={values || []}
|
options={options}
|
||||||
getOptionLabel={option => option.label}
|
value={values || []}
|
||||||
getOptionSelected={(option, value) =>
|
getOptionLabel={option => option.label}
|
||||||
option.value === value.value
|
onBlur={onBlur}
|
||||||
}
|
onFocus={() => resetError()}
|
||||||
filterSelectedOptions
|
getOptionSelected={(option, value) =>
|
||||||
filterOptions={options =>
|
option.value === value.value
|
||||||
options.filter(
|
}
|
||||||
o => !values.some(v => v.value === o.value)
|
filterSelectedOptions
|
||||||
)
|
filterOptions={options =>
|
||||||
}
|
options.filter(
|
||||||
onChange={(evt, values) =>
|
o =>
|
||||||
handleChangeValue(values)
|
!values.some(
|
||||||
}
|
v => v.value === o.value
|
||||||
renderInput={params => (
|
)
|
||||||
<TextField
|
)
|
||||||
{...params}
|
}
|
||||||
variant="outlined"
|
onChange={(evt, values) =>
|
||||||
label="Values"
|
handleChangeValue(values)
|
||||||
/>
|
}
|
||||||
)}
|
renderInput={params => (
|
||||||
/>
|
<TextField
|
||||||
|
{...params}
|
||||||
|
variant="outlined"
|
||||||
|
label={'Values'}
|
||||||
|
error={Boolean(error)}
|
||||||
|
helperText={error}
|
||||||
|
FormHelperTextProps={{
|
||||||
|
classes: {
|
||||||
|
root: styles.helperText,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
elseShow={
|
elseShow={
|
||||||
<InputListField
|
<div className={styles.inputContainer}>
|
||||||
name="values"
|
<InputListField
|
||||||
error={error}
|
name="values"
|
||||||
onBlur={onBlur}
|
error={Boolean(error)}
|
||||||
values={constraint.values}
|
onBlur={onBlur}
|
||||||
label="Values (v1, v2, v3)"
|
values={constraint.values}
|
||||||
updateValues={values =>
|
label="Values (v1, v2, v3)"
|
||||||
updateConstraint(values, 'values')
|
updateValues={values =>
|
||||||
}
|
updateConstraint(values, 'values')
|
||||||
/>
|
}
|
||||||
|
helperText={error}
|
||||||
|
FormHelperTextProps={{
|
||||||
|
classes: {
|
||||||
|
root: styles.helperText,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td className={styles.tableCell}>
|
||||||
<IconButton onClick={removeConstraint}>
|
<IconButton onClick={removeConstraint}>
|
||||||
<Delete />
|
<Delete />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
@ -7,4 +7,21 @@ export const useStyles = makeStyles({
|
|||||||
operator: {
|
operator: {
|
||||||
minWidth: '105px',
|
minWidth: '105px',
|
||||||
},
|
},
|
||||||
|
inputContainer: {
|
||||||
|
position: 'relative',
|
||||||
|
},
|
||||||
|
inputError: {
|
||||||
|
position: 'absolute',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
color: 'red',
|
||||||
|
top: '10px',
|
||||||
|
left: '12px',
|
||||||
|
},
|
||||||
|
tableCell: {
|
||||||
|
paddingBottom: '1.25rem',
|
||||||
|
},
|
||||||
|
helperText: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: '35px',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -187,6 +187,8 @@ const AddVariant = ({
|
|||||||
primaryButtonText="Save"
|
primaryButtonText="Save"
|
||||||
secondaryButtonText="Cancel"
|
secondaryButtonText="Cancel"
|
||||||
title={title}
|
title={title}
|
||||||
|
fullWidth
|
||||||
|
maxWidth="md"
|
||||||
>
|
>
|
||||||
<form onSubmit={submit} className={commonStyles.contentSpacingY}>
|
<form onSubmit={submit} className={commonStyles.contentSpacingY}>
|
||||||
<p style={{ color: 'red' }}>{error.general}</p>
|
<p style={{ color: 'red' }}>{error.general}</p>
|
||||||
@ -195,6 +197,7 @@ const AddVariant = ({
|
|||||||
name="name"
|
name="name"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
className={commonStyles.fullWidth}
|
className={commonStyles.fullWidth}
|
||||||
|
style={{ maxWidth: '350px' }}
|
||||||
helperText={error.name}
|
helperText={error.name}
|
||||||
value={data.name || ''}
|
value={data.name || ''}
|
||||||
error={Boolean(error.name)}
|
error={Boolean(error.name)}
|
||||||
@ -250,11 +253,17 @@ const AddVariant = ({
|
|||||||
title="Passed to the variant object. Can be anything
|
title="Passed to the variant object. Can be anything
|
||||||
(json, value, csv)"
|
(json, value, csv)"
|
||||||
>
|
>
|
||||||
<Info style={{ width: '18.5px', height: '18.5px' }} />
|
<Info
|
||||||
|
style={{
|
||||||
|
width: '18.5px',
|
||||||
|
height: '18.5px',
|
||||||
|
color: 'grey',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</p>
|
</p>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid item md={3}>
|
<Grid item md={2} sm={2} xs={4}>
|
||||||
<MySelect
|
<MySelect
|
||||||
name="type"
|
name="type"
|
||||||
label="Type"
|
label="Type"
|
||||||
@ -262,10 +271,10 @@ const AddVariant = ({
|
|||||||
value={payload.type}
|
value={payload.type}
|
||||||
options={payloadOptions}
|
options={payloadOptions}
|
||||||
onChange={onPayload}
|
onChange={onPayload}
|
||||||
style={{ minWidth: '100px' }}
|
style={{ minWidth: '100px', width: '100%' }}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item md={9}>
|
<Grid item md={8} sm={8} xs={6}>
|
||||||
<TextField
|
<TextField
|
||||||
rows={1}
|
rows={1}
|
||||||
label="Value"
|
label="Value"
|
||||||
@ -281,13 +290,14 @@ const AddVariant = ({
|
|||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={overrides.length > 0}
|
condition={overrides.length > 0}
|
||||||
show={
|
show={
|
||||||
<p style={{ marginBottom: '.5rem' }}>
|
<p style={{ marginBottom: '1rem' }}>
|
||||||
<strong>Overrides </strong>
|
<strong>Overrides </strong>
|
||||||
<Tooltip title="Here you can specify which users should get this variant.">
|
<Tooltip title="Here you can specify which users should get this variant.">
|
||||||
<Info
|
<Info
|
||||||
style={{
|
style={{
|
||||||
width: '18.5px',
|
width: '18.5px',
|
||||||
height: '18.5px',
|
height: '18.5px',
|
||||||
|
color: 'grey',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -301,7 +311,13 @@ const AddVariant = ({
|
|||||||
updateOverrideValues={updateOverrideValues}
|
updateOverrideValues={updateOverrideValues}
|
||||||
updateValues={updateOverrideValues}
|
updateValues={updateOverrideValues}
|
||||||
/>
|
/>
|
||||||
<Button onClick={onAddOverride}>Add override</Button>{' '}
|
<Button
|
||||||
|
onClick={onAddOverride}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
Add override
|
||||||
|
</Button>{' '}
|
||||||
</form>
|
</form>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
@ -41,7 +41,13 @@ const OverrideConfig = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container key={`override=${i}`} alignItems="center">
|
<Grid container key={`override=${i}`} alignItems="center">
|
||||||
<Grid item md={3} className={styles.contextFieldSelect}>
|
<Grid
|
||||||
|
item
|
||||||
|
md={3}
|
||||||
|
sm={3}
|
||||||
|
xs={3}
|
||||||
|
className={styles.contextFieldSelect}
|
||||||
|
>
|
||||||
<MySelect
|
<MySelect
|
||||||
name="contextName"
|
name="contextName"
|
||||||
label="Context Field"
|
label="Context Field"
|
||||||
@ -53,7 +59,7 @@ const OverrideConfig = ({
|
|||||||
onChange={updateOverrideType(i)}
|
onChange={updateOverrideType(i)}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid md={7} item>
|
<Grid md={7} sm={7} xs={6} item>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={legalValues && legalValues.length > 0}
|
condition={legalValues && legalValues.length > 0}
|
||||||
show={
|
show={
|
||||||
@ -68,6 +74,7 @@ const OverrideConfig = ({
|
|||||||
getOptionLabel={option => option}
|
getOptionLabel={option => option}
|
||||||
defaultValue={o.values}
|
defaultValue={o.values}
|
||||||
value={o.values}
|
value={o.values}
|
||||||
|
style={{ width: '100%' }}
|
||||||
filterSelectedOptions
|
filterSelectedOptions
|
||||||
size="small"
|
size="small"
|
||||||
renderInput={params => (
|
renderInput={params => (
|
||||||
@ -75,6 +82,7 @@ const OverrideConfig = ({
|
|||||||
{...params}
|
{...params}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
label="Legal values"
|
label="Legal values"
|
||||||
|
style={{ width: '100%' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -16,255 +16,253 @@ export const Footer = () => {
|
|||||||
<Grid item md={4} xs={12}>
|
<Grid item md={4} xs={12}>
|
||||||
<ShowApiDetailsContainer />
|
<ShowApiDetailsContainer />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs="12" md="auto">
|
<Grid item xs={12} md="auto">
|
||||||
<Grid container spacing={7} direction="row" >
|
<Grid container spacing={7} direction="row">
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<section title="Unleash SDK">
|
<section title="Unleash SDK">
|
||||||
<h4>Server SDKs</h4>
|
<h4>Server SDKs</h4>
|
||||||
<List className={styles.list} dense>
|
<List className={styles.list} dense>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/node_sdk"
|
href="https://docs.getunleash.io/sdks/node_sdk"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Node.js
|
Node.js
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/java_sdk"
|
href="https://docs.getunleash.io/sdks/java_sdk"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Java
|
Java
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/go_sdk"
|
href="https://docs.getunleash.io/sdks/go_sdk"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Go
|
Go
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>{' '}
|
</ListItem>{' '}
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/ruby_sdk"
|
href="https://docs.getunleash.io/sdks/ruby_sdk"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Ruby
|
Ruby
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>{' '}
|
</ListItem>{' '}
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/python_sdk"
|
href="https://docs.getunleash.io/sdks/python_sdk"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Python
|
Python
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/dot_net_sdk"
|
href="https://docs.getunleash.io/sdks/dot_net_sdk"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
.NET
|
.NET
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/php_sdk"
|
href="https://docs.getunleash.io/sdks/php_sdk"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
PHP
|
PHP
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks"
|
href="https://docs.getunleash.io/sdks"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
All SDKs
|
All SDKs
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
</section>
|
</section>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item justifyContent="center">
|
<Grid item>
|
||||||
<section title="Unleash SDK">
|
<section title="Unleash SDK">
|
||||||
<h4>Frontend SDKs</h4>
|
<h4>Frontend SDKs</h4>
|
||||||
<List className={styles.list} dense>
|
<List className={styles.list} dense>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/unleash-proxy"
|
href="https://docs.getunleash.io/sdks/unleash-proxy"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Unleash Proxy
|
Unleash Proxy
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/proxy-javascript"
|
href="https://docs.getunleash.io/sdks/proxy-javascript"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
JavaScript SDK
|
JavaScript SDK
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/proxy-react"
|
href="https://docs.getunleash.io/sdks/proxy-react"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
React SDK
|
React SDK
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/proxy-ios"
|
href="https://docs.getunleash.io/sdks/proxy-ios"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
iOS SDK
|
iOS SDK
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://docs.getunleash.io/sdks/android_proxy_sdk"
|
href="https://docs.getunleash.io/sdks/android_proxy_sdk"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Android SDK
|
Android SDK
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
</section>
|
</section>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<section>
|
<section>
|
||||||
<h4>About</h4>
|
<h4>About</h4>
|
||||||
<List className={styles.list} dense>
|
<List className={styles.list} dense>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://www.getunleash.io/"
|
href="https://www.getunleash.io/"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
getunleash.io
|
getunleash.io
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://twitter.com/getunleash"
|
href="https://twitter.com/getunleash"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Twitter
|
Twitter
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://www.linkedin.com/company/getunleash"
|
href="https://www.linkedin.com/company/getunleash"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
LinkedIn
|
LinkedIn
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem className={styles.listItem}>
|
<ListItem className={styles.listItem}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={
|
primary={
|
||||||
<a
|
<a
|
||||||
href="https://github.com/Unleash/unleash"
|
href="https://github.com/Unleash/unleash"
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
GitHub
|
GitHub
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
</section>
|
</section>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
|
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -199,7 +199,6 @@ exports[`should render DrawerMenu 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="MuiGrid-root MuiGrid-item"
|
className="MuiGrid-root MuiGrid-item"
|
||||||
justifyContent="center"
|
|
||||||
>
|
>
|
||||||
<section
|
<section
|
||||||
title="Unleash SDK"
|
title="Unleash SDK"
|
||||||
@ -602,7 +601,6 @@ exports[`should render DrawerMenu with "features" selected 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="MuiGrid-root MuiGrid-item"
|
className="MuiGrid-root MuiGrid-item"
|
||||||
justifyContent="center"
|
|
||||||
>
|
>
|
||||||
<section
|
<section
|
||||||
title="Unleash SDK"
|
title="Unleash SDK"
|
||||||
|
Loading…
Reference in New Issue
Block a user