mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
feat: add context value descriptions (#874)
* feat: add context value descriptions * refcator: use ConditionallyRender for ...conditional render * refactor: fix context form enter behaviour * refactor: decrease margin between inputs * refactor: show error on missing value * refactor: disable add button on error * refactor: avoid clearing value error on name focus
This commit is contained in:
parent
9200e74c90
commit
cb8add5c30
@ -0,0 +1,16 @@
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export const useStyles = makeStyles(theme => ({
|
||||
container: {
|
||||
display: 'inline-block',
|
||||
},
|
||||
value: {
|
||||
lineHeight: 1.33,
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
},
|
||||
description: {
|
||||
lineHeight: 1.33,
|
||||
fontSize: theme.fontSizes.smallerBody,
|
||||
color: theme.palette.grey[700],
|
||||
},
|
||||
}));
|
@ -0,0 +1,39 @@
|
||||
import { ILegalValue } from 'interfaces/context';
|
||||
import { useStyles } from './LegalValueLabel.styles';
|
||||
import React from 'react';
|
||||
import { FormControlLabel } from '@material-ui/core';
|
||||
|
||||
interface ILegalValueTextProps {
|
||||
legal: ILegalValue;
|
||||
control: React.ReactElement;
|
||||
}
|
||||
|
||||
export const LegalValueLabel = ({ legal, control }: ILegalValueTextProps) => {
|
||||
const styles = useStyles();
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<FormControlLabel
|
||||
value={legal.value}
|
||||
control={control}
|
||||
label={
|
||||
<>
|
||||
<div className={styles.value}>{legal.value}</div>
|
||||
<div className={styles.description}>
|
||||
{legal.description}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const filterLegalValues = (
|
||||
legalValues: ILegalValue[],
|
||||
filter: string
|
||||
): ILegalValue[] => {
|
||||
return legalValues.filter(legalValue => {
|
||||
return legalValue.value.includes(filter);
|
||||
});
|
||||
};
|
@ -18,6 +18,7 @@ import {
|
||||
IN_OPERATORS_FREETEXT,
|
||||
Input,
|
||||
} from '../useConstraintInput/useConstraintInput';
|
||||
import React from 'react';
|
||||
|
||||
interface IResolveInputProps {
|
||||
contextDefinition: IUnleashContextDefinition;
|
||||
@ -81,7 +82,7 @@ export const ResolveInput = ({
|
||||
type="number"
|
||||
legalValues={
|
||||
contextDefinition.legalValues?.filter(
|
||||
(value: string) => Number(value)
|
||||
legalValue => Number(legalValue.value)
|
||||
) || []
|
||||
}
|
||||
error={error}
|
||||
|
@ -1,13 +1,17 @@
|
||||
import { Checkbox, FormControlLabel } from '@material-ui/core';
|
||||
import { Checkbox } from '@material-ui/core';
|
||||
import { useCommonStyles } from 'themes/commonStyles';
|
||||
import ConditionallyRender from 'component/common/ConditionallyRender';
|
||||
import { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ConstraintValueSearch } from 'component/common/ConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch';
|
||||
import { ConstraintFormHeader } from '../ConstraintFormHeader/ConstraintFormHeader';
|
||||
import { ILegalValue } from 'interfaces/context';
|
||||
import {
|
||||
LegalValueLabel,
|
||||
filterLegalValues,
|
||||
} from '../LegalValueLabel/LegalValueLabel';
|
||||
|
||||
// Parent component
|
||||
interface IRestrictiveLegalValuesProps {
|
||||
legalValues: string[];
|
||||
legalValues: ILegalValue[];
|
||||
values: string[];
|
||||
setValues: (values: string[]) => void;
|
||||
beforeValues?: JSX.Element;
|
||||
@ -36,6 +40,8 @@ export const RestrictiveLegalValues = ({
|
||||
setError,
|
||||
}: IRestrictiveLegalValuesProps) => {
|
||||
const [filter, setFilter] = useState('');
|
||||
const filteredValues = filterLegalValues(legalValues, filter);
|
||||
|
||||
// Lazily initialise the values because there might be a lot of them.
|
||||
const [valuesMap, setValuesMap] = useState(() => createValuesMap(values));
|
||||
const styles = useCommonStyles();
|
||||
@ -63,12 +69,20 @@ export const RestrictiveLegalValues = ({
|
||||
Select values from a predefined set
|
||||
</ConstraintFormHeader>
|
||||
<ConstraintValueSearch filter={filter} setFilter={setFilter} />
|
||||
<LegalValueOptions
|
||||
legalValues={legalValues}
|
||||
filter={filter}
|
||||
onChange={onChange}
|
||||
valuesMap={valuesMap}
|
||||
{filteredValues.map(match => (
|
||||
<LegalValueLabel
|
||||
key={match.value}
|
||||
legal={match}
|
||||
control={
|
||||
<Checkbox
|
||||
checked={Boolean(valuesMap[match.value])}
|
||||
onChange={() => onChange(match.value)}
|
||||
name={match.value}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
))}
|
||||
<ConditionallyRender
|
||||
condition={Boolean(error)}
|
||||
show={<p className={styles.error}>{error}</p>}
|
||||
@ -76,41 +90,3 @@ export const RestrictiveLegalValues = ({
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// Child component
|
||||
interface ILegalValueOptionsProps {
|
||||
legalValues: string[];
|
||||
filter: string;
|
||||
onChange: (legalValue: string) => void;
|
||||
valuesMap: IValuesMap;
|
||||
}
|
||||
|
||||
const LegalValueOptions = ({
|
||||
legalValues,
|
||||
filter,
|
||||
onChange,
|
||||
valuesMap,
|
||||
}: ILegalValueOptionsProps) => {
|
||||
return (
|
||||
<>
|
||||
{legalValues
|
||||
.filter(legalValue => legalValue.includes(filter))
|
||||
.map(legalValue => {
|
||||
return (
|
||||
<FormControlLabel
|
||||
key={legalValue}
|
||||
control={
|
||||
<Checkbox
|
||||
checked={Boolean(valuesMap[legalValue])}
|
||||
onChange={() => onChange(legalValue)}
|
||||
color="primary"
|
||||
name={legalValue}
|
||||
/>
|
||||
}
|
||||
label={legalValue}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,23 +1,20 @@
|
||||
import { useState } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { ConstraintFormHeader } from '../ConstraintFormHeader/ConstraintFormHeader';
|
||||
import {
|
||||
FormControl,
|
||||
FormLabel,
|
||||
FormControlLabel,
|
||||
RadioGroup,
|
||||
Radio,
|
||||
} from '@material-ui/core';
|
||||
import { FormControl, RadioGroup, Radio } from '@material-ui/core';
|
||||
import { ConstraintValueSearch } from 'component/common/ConstraintAccordion/ConstraintValueSearch/ConstraintValueSearch';
|
||||
import ConditionallyRender from 'component/common/ConditionallyRender';
|
||||
import { useCommonStyles } from 'themes/commonStyles';
|
||||
|
||||
// Parent component
|
||||
import { ILegalValue } from 'interfaces/context';
|
||||
import {
|
||||
LegalValueLabel,
|
||||
filterLegalValues,
|
||||
} from '../LegalValueLabel/LegalValueLabel';
|
||||
|
||||
interface ISingleLegalValueProps {
|
||||
setValue: (value: string) => void;
|
||||
value?: string;
|
||||
type: string;
|
||||
legalValues: string[];
|
||||
legalValues: ILegalValue[];
|
||||
error: string;
|
||||
setError: React.Dispatch<React.SetStateAction<string>>;
|
||||
}
|
||||
@ -32,21 +29,18 @@ export const SingleLegalValue = ({
|
||||
}: ISingleLegalValueProps) => {
|
||||
const [filter, setFilter] = useState('');
|
||||
const styles = useCommonStyles();
|
||||
const filteredValues = filterLegalValues(legalValues, filter);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConstraintFormHeader>
|
||||
Add a single {type.toLowerCase()} value
|
||||
</ConstraintFormHeader>
|
||||
|
||||
<ConstraintValueSearch filter={filter} setFilter={setFilter} />
|
||||
<ConditionallyRender
|
||||
condition={Boolean(legalValues.length)}
|
||||
show={
|
||||
<FormControl component="fieldset">
|
||||
<FormLabel component="legend">
|
||||
Available values
|
||||
</FormLabel>
|
||||
<RadioGroup
|
||||
aria-label="selected-value"
|
||||
name="selected"
|
||||
@ -56,10 +50,13 @@ export const SingleLegalValue = ({
|
||||
setValue(e.target.value);
|
||||
}}
|
||||
>
|
||||
<RadioOptions
|
||||
legalValues={legalValues}
|
||||
filter={filter}
|
||||
{filteredValues.map(match => (
|
||||
<LegalValueLabel
|
||||
key={match.value}
|
||||
legal={match}
|
||||
control={<Radio />}
|
||||
/>
|
||||
))}
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
}
|
||||
@ -74,28 +71,3 @@ export const SingleLegalValue = ({
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
// Child components
|
||||
interface IRadioOptionsProps {
|
||||
legalValues: string[];
|
||||
filter: string;
|
||||
}
|
||||
|
||||
const RadioOptions = ({ legalValues, filter }: IRadioOptionsProps) => {
|
||||
return (
|
||||
<>
|
||||
{legalValues
|
||||
.filter(legalValue => legalValue.includes(filter))
|
||||
.map((value, index) => {
|
||||
return (
|
||||
<FormControlLabel
|
||||
key={`${value}-${index}`}
|
||||
value={value}
|
||||
control={<Radio />}
|
||||
label={value}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,36 @@
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export const useStyles = makeStyles(theme => ({
|
||||
container: {
|
||||
display: 'grid',
|
||||
lineHeight: 1.25,
|
||||
gridTemplateColumns: '1fr auto',
|
||||
alignSelf: 'start',
|
||||
alignItems: 'start',
|
||||
gap: '0.5rem',
|
||||
padding: '0.5rem',
|
||||
background: theme.palette.grey[200],
|
||||
borderRadius: theme.borders.radius.main,
|
||||
},
|
||||
label: {
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
},
|
||||
description: {
|
||||
fontSize: theme.fontSizes.smallerBody,
|
||||
color: theme.palette.grey[700],
|
||||
},
|
||||
button: {
|
||||
all: 'unset',
|
||||
lineHeight: 0.1,
|
||||
paddingTop: 1,
|
||||
display: 'block',
|
||||
cursor: 'pointer',
|
||||
'& svg': {
|
||||
fontSize: '1rem',
|
||||
opacity: 0.5,
|
||||
},
|
||||
'&:hover svg, &:focus-visible svg': {
|
||||
opacity: 0.75,
|
||||
},
|
||||
},
|
||||
}));
|
@ -0,0 +1,34 @@
|
||||
import { useStyles } from 'component/context/ContectFormChip/ContextFormChip.styles';
|
||||
import { Cancel } from '@material-ui/icons';
|
||||
import ConditionallyRender from 'component/common/ConditionallyRender';
|
||||
|
||||
interface IContextFormChipProps {
|
||||
label: string;
|
||||
description?: string;
|
||||
onRemove: () => void;
|
||||
}
|
||||
|
||||
export const ContextFormChip = ({
|
||||
label,
|
||||
description,
|
||||
onRemove,
|
||||
}: IContextFormChipProps) => {
|
||||
const styles = useStyles();
|
||||
|
||||
return (
|
||||
<li className={styles.container}>
|
||||
<div>
|
||||
<div className={styles.label}>{label}</div>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(description)}
|
||||
show={() => (
|
||||
<div className={styles.description}>{description}</div>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<button onClick={onRemove} className={styles.button}>
|
||||
<Cancel titleAccess="Remove" />
|
||||
</button>
|
||||
</li>
|
||||
);
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
export const useStyles = makeStyles(theme => ({
|
||||
container: {
|
||||
listStyleType: 'none',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
gap: '0.5rem',
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
marginBottom: '1rem !important',
|
||||
},
|
||||
}));
|
@ -0,0 +1,8 @@
|
||||
import { useStyles } from 'component/context/ContectFormChip/ContextFormChipList.styles';
|
||||
import React from 'react';
|
||||
|
||||
export const ContextFormChipList: React.FC = ({ children }) => {
|
||||
const styles = useStyles();
|
||||
|
||||
return <ul className={styles.container}>{children}</ul>;
|
||||
};
|
@ -20,17 +20,16 @@ export const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
},
|
||||
tagContainer: {
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr auto',
|
||||
gap: '0.5rem',
|
||||
marginBottom: '1rem',
|
||||
},
|
||||
tagInput: {
|
||||
width: '75%',
|
||||
marginRight: 'auto',
|
||||
gridColumn: 1,
|
||||
},
|
||||
tagValue: {
|
||||
marginRight: '3px',
|
||||
marginBottom: '1rem',
|
||||
tagButton: {
|
||||
gridColumn: 2,
|
||||
},
|
||||
buttonContainer: {
|
||||
marginTop: 'auto',
|
||||
|
@ -1,24 +1,26 @@
|
||||
import Input from 'component/common/Input/Input';
|
||||
import { TextField, Button, Switch, Chip, Typography } from '@material-ui/core';
|
||||
import { TextField, Button, Switch, Typography } from '@material-ui/core';
|
||||
import { useStyles } from './ContextForm.styles';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Add } from '@material-ui/icons';
|
||||
import { trim } from 'component/common/util';
|
||||
import { ILegalValue } from 'interfaces/context';
|
||||
import { ContextFormChip } from 'component/context/ContectFormChip/ContextFormChip';
|
||||
import { ContextFormChipList } from 'component/context/ContectFormChip/ContextFormChipList';
|
||||
|
||||
interface IContextForm {
|
||||
contextName: string;
|
||||
contextDesc: string;
|
||||
legalValues: Array<string>;
|
||||
legalValues: ILegalValue[];
|
||||
stickiness: boolean;
|
||||
setContextName: React.Dispatch<React.SetStateAction<string>>;
|
||||
setContextDesc: React.Dispatch<React.SetStateAction<string>>;
|
||||
setStickiness: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
setLegalValues: React.Dispatch<React.SetStateAction<string[]>>;
|
||||
setLegalValues: React.Dispatch<React.SetStateAction<ILegalValue[]>>;
|
||||
handleSubmit: (e: any) => void;
|
||||
onCancel: () => void;
|
||||
errors: { [key: string]: string };
|
||||
mode: 'Create' | 'Edit';
|
||||
clearErrors: () => void;
|
||||
clearErrors: (key?: string) => void;
|
||||
validateContext?: () => void;
|
||||
setErrors: React.Dispatch<React.SetStateAction<Object>>;
|
||||
}
|
||||
@ -45,54 +47,64 @@ export const ContextForm: React.FC<IContextForm> = ({
|
||||
}) => {
|
||||
const styles = useStyles();
|
||||
const [value, setValue] = useState('');
|
||||
const [focused, setFocused] = useState(false);
|
||||
const [valueDesc, setValueDesc] = useState('');
|
||||
const [valueFocused, setValueFocused] = useState(false);
|
||||
|
||||
const submit = (event: React.SyntheticEvent) => {
|
||||
const isMissingValue = valueDesc.trim() && !value.trim();
|
||||
|
||||
const isDuplicateValue = legalValues.some(legalValue => {
|
||||
return legalValue.value.trim() === value.trim();
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setErrors(prev => ({
|
||||
...prev,
|
||||
tag: isMissingValue
|
||||
? 'Value cannot be empty'
|
||||
: isDuplicateValue
|
||||
? 'Duplicate value'
|
||||
: undefined,
|
||||
}));
|
||||
}, [setErrors, isMissingValue, isDuplicateValue]);
|
||||
|
||||
const onSubmit = (event: React.SyntheticEvent) => {
|
||||
event.preventDefault();
|
||||
if (focused) return;
|
||||
handleSubmit(event);
|
||||
};
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent) => {
|
||||
if (event.key === ENTER && focused) {
|
||||
const onKeyDown = (event: React.KeyboardEvent) => {
|
||||
if (event.key === ENTER) {
|
||||
event.preventDefault();
|
||||
if (valueFocused) {
|
||||
addLegalValue();
|
||||
return;
|
||||
} else if (event.key === ENTER) {
|
||||
} else {
|
||||
handleSubmit(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const sortIgnoreCase = (a: string, b: string) => {
|
||||
a = a.toLowerCase();
|
||||
b = b.toLowerCase();
|
||||
if (a === b) return 0;
|
||||
if (a > b) return 1;
|
||||
return -1;
|
||||
const sortLegalValues = (a: ILegalValue, b: ILegalValue) => {
|
||||
return a.value.toLowerCase().localeCompare(b.value.toLowerCase());
|
||||
};
|
||||
|
||||
const addLegalValue = () => {
|
||||
clearErrors();
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (legalValues.indexOf(value) !== -1) {
|
||||
setErrors(prev => ({
|
||||
...prev,
|
||||
tag: 'Duplicate legal value',
|
||||
}));
|
||||
return;
|
||||
}
|
||||
setLegalValues(prev => [...prev, trim(value)].sort(sortIgnoreCase));
|
||||
setValue('');
|
||||
const next: ILegalValue = {
|
||||
value: value.trim(),
|
||||
description: valueDesc.trim(),
|
||||
};
|
||||
const removeLegalValue = (index: number) => {
|
||||
const filteredValues = legalValues.filter((_, i) => i !== index);
|
||||
setLegalValues([...filteredValues]);
|
||||
if (next.value && !isDuplicateValue) {
|
||||
setValue('');
|
||||
setValueDesc('');
|
||||
setLegalValues(prev => [...prev, next].sort(sortLegalValues));
|
||||
}
|
||||
};
|
||||
|
||||
const removeLegalValue = (value: ILegalValue) => {
|
||||
setLegalValues(prev => prev.filter(p => p.value !== value.value));
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={submit} className={styles.form}>
|
||||
<form onSubmit={onSubmit} className={styles.form}>
|
||||
<div className={styles.container}>
|
||||
<p className={styles.inputDescription}>
|
||||
What is your context name?
|
||||
@ -102,10 +114,10 @@ export const ContextForm: React.FC<IContextForm> = ({
|
||||
label="Context name"
|
||||
value={contextName}
|
||||
disabled={mode === 'Edit'}
|
||||
onChange={e => setContextName(trim(e.target.value))}
|
||||
onChange={e => setContextName(e.target.value.trim())}
|
||||
error={Boolean(errors.name)}
|
||||
errorText={errors.name}
|
||||
onFocus={() => clearErrors()}
|
||||
onFocus={() => clearErrors('name')}
|
||||
onBlur={validateContext}
|
||||
autoFocus
|
||||
/>
|
||||
@ -119,25 +131,15 @@ export const ContextForm: React.FC<IContextForm> = ({
|
||||
multiline
|
||||
maxRows={4}
|
||||
value={contextDesc}
|
||||
size="small"
|
||||
onChange={e => setContextDesc(e.target.value)}
|
||||
/>
|
||||
<p className={styles.inputDescription}>
|
||||
Which values do you want to allow?
|
||||
</p>
|
||||
{legalValues.map((value, index) => {
|
||||
return (
|
||||
<Chip
|
||||
key={index + value}
|
||||
label={value}
|
||||
className={styles.tagValue}
|
||||
onDelete={() => removeLegalValue(index)}
|
||||
title="Remove value"
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<div className={styles.tagContainer}>
|
||||
<TextField
|
||||
label="Value (optional)"
|
||||
label="Legal value (optional)"
|
||||
name="value"
|
||||
className={styles.tagInput}
|
||||
value={value}
|
||||
@ -145,20 +147,47 @@ export const ContextForm: React.FC<IContextForm> = ({
|
||||
helperText={errors.tag}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
onChange={e => setValue(trim(e.target.value))}
|
||||
onKeyPress={e => handleKeyDown(e)}
|
||||
onBlur={e => setFocused(false)}
|
||||
onFocus={e => setFocused(true)}
|
||||
onChange={e => setValue(e.target.value)}
|
||||
onKeyPress={e => onKeyDown(e)}
|
||||
onBlur={() => setValueFocused(false)}
|
||||
onFocus={() => setValueFocused(true)}
|
||||
inputProps={{ maxLength: 100 }}
|
||||
/>
|
||||
<TextField
|
||||
label="Value description (optional)"
|
||||
className={styles.tagInput}
|
||||
value={valueDesc}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
onChange={e => setValueDesc(e.target.value)}
|
||||
onKeyPress={e => onKeyDown(e)}
|
||||
onBlur={() => setValueFocused(false)}
|
||||
onFocus={() => setValueFocused(true)}
|
||||
inputProps={{ maxLength: 100 }}
|
||||
/>
|
||||
<Button
|
||||
className={styles.tagButton}
|
||||
startIcon={<Add />}
|
||||
onClick={addLegalValue}
|
||||
variant="contained"
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
disabled={!value.trim() || isDuplicateValue}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
</div>
|
||||
<ContextFormChipList>
|
||||
{legalValues.map(legalValue => {
|
||||
return (
|
||||
<ContextFormChip
|
||||
key={legalValue.value}
|
||||
label={legalValue.value}
|
||||
description={legalValue.description}
|
||||
onRemove={() => removeLegalValue(legalValue)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ContextFormChipList>
|
||||
<p className={styles.inputHeader}>Custom stickiness</p>
|
||||
<p>
|
||||
By enabling stickiness on this context field you can use it
|
||||
|
@ -1,26 +1,27 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import useContextsApi from 'hooks/api/actions/useContextsApi/useContextsApi';
|
||||
import { ILegalValue } from 'interfaces/context';
|
||||
|
||||
export const useContextForm = (
|
||||
initialcontextName = '',
|
||||
initialcontextDesc = '',
|
||||
initialLegalValues = [] as string[],
|
||||
initialContextName = '',
|
||||
initialContextDesc = '',
|
||||
initialLegalValues = [] as ILegalValue[],
|
||||
initialStickiness = false
|
||||
) => {
|
||||
const [contextName, setContextName] = useState(initialcontextName);
|
||||
const [contextDesc, setContextDesc] = useState(initialcontextDesc);
|
||||
const [contextName, setContextName] = useState(initialContextName);
|
||||
const [contextDesc, setContextDesc] = useState(initialContextDesc);
|
||||
const [legalValues, setLegalValues] = useState(initialLegalValues);
|
||||
const [stickiness, setStickiness] = useState(initialStickiness);
|
||||
const [errors, setErrors] = useState({});
|
||||
const { validateContextName } = useContextsApi();
|
||||
|
||||
useEffect(() => {
|
||||
setContextName(initialcontextName);
|
||||
}, [initialcontextName]);
|
||||
setContextName(initialContextName);
|
||||
}, [initialContextName]);
|
||||
|
||||
useEffect(() => {
|
||||
setContextDesc(initialcontextDesc);
|
||||
}, [initialcontextDesc]);
|
||||
setContextDesc(initialContextDesc);
|
||||
}, [initialContextDesc]);
|
||||
|
||||
useEffect(() => {
|
||||
setLegalValues(initialLegalValues);
|
||||
@ -66,8 +67,12 @@ export const useContextForm = (
|
||||
}
|
||||
};
|
||||
|
||||
const clearErrors = () => {
|
||||
const clearErrors = (key?: string) => {
|
||||
if (key) {
|
||||
setErrors(prev => ({ ...prev, [key]: undefined }));
|
||||
} else {
|
||||
setErrors({});
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -4,5 +4,10 @@ export interface IUnleashContextDefinition {
|
||||
createdAt: string;
|
||||
sortOrder: number;
|
||||
stickiness: boolean;
|
||||
legalValues?: string[];
|
||||
legalValues?: ILegalValue[];
|
||||
}
|
||||
|
||||
export interface ILegalValue {
|
||||
value: string;
|
||||
description?: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user