mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-18 13:48:58 +02:00
clean some more
This commit is contained in:
parent
47843b3c52
commit
275cac95c5
@ -28,7 +28,7 @@ const AddValuesButton = styled('button')(({ theme }) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
interface AddValuesProps {
|
interface AddValuesProps {
|
||||||
onAddValues: (newValues: string[]) => void;
|
onAddValues: (newValues: Set<string>) => void;
|
||||||
helpText?: string;
|
helpText?: string;
|
||||||
validator: (...values: string[]) => ConstraintValidatorOutput;
|
validator: (...values: string[]) => ConstraintValidatorOutput;
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ export const AddValuesWidget = forwardRef<HTMLButtonElement, AddValuesProps>(
|
|||||||
|
|
||||||
const [isValid, errorMessage] = validator(...newValues);
|
const [isValid, errorMessage] = validator(...newValues);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
onAddValues(newValues);
|
onAddValues(new Set(newValues));
|
||||||
clearInput();
|
clearInput();
|
||||||
setError('');
|
setError('');
|
||||||
} else {
|
} else {
|
||||||
|
@ -167,6 +167,9 @@ const getInputType = (input: Input): InputType => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ConstraintWithValueSet = Omit<IConstraint, 'values'> & {
|
||||||
|
values?: Set<string>;
|
||||||
|
};
|
||||||
type ConstraintUpdateAction =
|
type ConstraintUpdateAction =
|
||||||
| { type: 'add value(s)'; payload: string[] }
|
| { type: 'add value(s)'; payload: string[] }
|
||||||
| { type: 'set value'; payload: string }
|
| { type: 'set value'; payload: string }
|
||||||
@ -178,7 +181,7 @@ type ConstraintUpdateAction =
|
|||||||
| { type: 'toggle inverted operator' };
|
| { type: 'toggle inverted operator' };
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
localConstraint: IConstraint;
|
localConstraint: ConstraintWithValueSet;
|
||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
contextDefinition: Pick<IUnleashContextDefinition, 'legalValues'>;
|
contextDefinition: Pick<IUnleashContextDefinition, 'legalValues'>;
|
||||||
constraintValues: string[];
|
constraintValues: string[];
|
||||||
@ -194,6 +197,7 @@ export const EditableConstraint: FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { input } = useConstraintInput({
|
const { input } = useConstraintInput({
|
||||||
contextDefinition,
|
contextDefinition,
|
||||||
|
// @ts-ignore
|
||||||
localConstraint,
|
localConstraint,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -352,7 +356,11 @@ export const EditableConstraint: FC<Props> = ({
|
|||||||
</OperatorOptions>
|
</OperatorOptions>
|
||||||
</ConstraintOptions>
|
</ConstraintOptions>
|
||||||
<ValueList
|
<ValueList
|
||||||
values={localConstraint.values}
|
values={
|
||||||
|
localConstraint.values
|
||||||
|
? Array.from(localConstraint.values)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
removeValue={(value) =>
|
removeValue={(value) =>
|
||||||
updateConstraint({
|
updateConstraint({
|
||||||
type: 'remove value from list',
|
type: 'remove value from list',
|
||||||
@ -388,7 +396,7 @@ export const EditableConstraint: FC<Props> = ({
|
|||||||
contextDefinition.legalValues,
|
contextDefinition.legalValues,
|
||||||
)}
|
)}
|
||||||
constraintValues={constraintValues}
|
constraintValues={constraintValues}
|
||||||
values={localConstraint.values || []}
|
values={localConstraint.values || new Set()}
|
||||||
clearAll={() =>
|
clearAll={() =>
|
||||||
updateConstraint({
|
updateConstraint({
|
||||||
type: 'clear values',
|
type: 'clear values',
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import type { IConstraint } from 'interfaces/strategy';
|
import type { IConstraint } from 'interfaces/strategy';
|
||||||
import { cleanConstraint } from 'utils/cleanConstraint';
|
|
||||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||||
import type { IUnleashContextDefinition } from 'interfaces/context';
|
import type { IUnleashContextDefinition } from 'interfaces/context';
|
||||||
import {
|
import {
|
||||||
DATE_AFTER,
|
DATE_AFTER,
|
||||||
dateOperators,
|
dateOperators,
|
||||||
IN,
|
IN,
|
||||||
|
singleValueOperators,
|
||||||
type Operator,
|
type Operator,
|
||||||
} from 'constants/operators';
|
} from 'constants/operators';
|
||||||
import { EditableConstraint } from 'component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint';
|
import { EditableConstraint } from 'component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint';
|
||||||
import { CURRENT_TIME_CONTEXT_FIELD } from 'utils/operatorsForContext';
|
import { CURRENT_TIME_CONTEXT_FIELD } from 'utils/operatorsForContext';
|
||||||
|
import produce from 'immer';
|
||||||
|
|
||||||
interface IConstraintAccordionEditProps {
|
interface IConstraintAccordionEditProps {
|
||||||
constraint: IConstraint;
|
constraint: IConstraint;
|
||||||
@ -50,15 +51,31 @@ type ConstraintUpdateAction =
|
|||||||
| { type: 'toggle case sensitivity' }
|
| { type: 'toggle case sensitivity' }
|
||||||
| { type: 'toggle inverted operator' };
|
| { type: 'toggle inverted operator' };
|
||||||
|
|
||||||
|
type ConstraintWithValueSet = Omit<IConstraint, 'values'> & {
|
||||||
|
values?: Set<string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const cleanConstraint = (
|
||||||
|
constraint: Readonly<ConstraintWithValueSet>,
|
||||||
|
): ConstraintWithValueSet => {
|
||||||
|
return produce(constraint, (draft) => {
|
||||||
|
if (singleValueOperators.includes(constraint.operator)) {
|
||||||
|
delete draft.values;
|
||||||
|
} else {
|
||||||
|
delete draft.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const EditableConstraintWrapper = ({
|
export const EditableConstraintWrapper = ({
|
||||||
constraint,
|
constraint,
|
||||||
onDelete,
|
onDelete,
|
||||||
onAutoSave,
|
onAutoSave,
|
||||||
}: IConstraintAccordionEditProps) => {
|
}: IConstraintAccordionEditProps) => {
|
||||||
const constraintReducer = (
|
const constraintReducer = (
|
||||||
state: IConstraint,
|
state: ConstraintWithValueSet,
|
||||||
action: ConstraintUpdateAction,
|
action: ConstraintUpdateAction,
|
||||||
): IConstraint => {
|
): ConstraintWithValueSet => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'set context field':
|
case 'set context field':
|
||||||
if (
|
if (
|
||||||
@ -68,7 +85,7 @@ export const EditableConstraintWrapper = ({
|
|||||||
return cleanConstraint({
|
return cleanConstraint({
|
||||||
...state,
|
...state,
|
||||||
operator: DATE_AFTER,
|
operator: DATE_AFTER,
|
||||||
values: [],
|
values: new Set(),
|
||||||
value: new Date().toISOString(),
|
value: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (
|
||||||
@ -78,7 +95,8 @@ export const EditableConstraintWrapper = ({
|
|||||||
return cleanConstraint({
|
return cleanConstraint({
|
||||||
...state,
|
...state,
|
||||||
operator: IN,
|
operator: IN,
|
||||||
values: [],
|
values: new Set(),
|
||||||
|
|
||||||
value: '',
|
value: '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -86,22 +104,23 @@ export const EditableConstraintWrapper = ({
|
|||||||
return cleanConstraint({
|
return cleanConstraint({
|
||||||
...state,
|
...state,
|
||||||
contextName: action.payload,
|
contextName: action.payload,
|
||||||
values: [],
|
values: new Set(),
|
||||||
|
|
||||||
value: '',
|
value: '',
|
||||||
});
|
});
|
||||||
case 'set operator':
|
case 'set operator':
|
||||||
return cleanConstraint({
|
return cleanConstraint({
|
||||||
...state,
|
...state,
|
||||||
operator: action.payload,
|
operator: action.payload,
|
||||||
values: [],
|
values: new Set(),
|
||||||
|
|
||||||
value: '',
|
value: '',
|
||||||
});
|
});
|
||||||
case 'add value(s)': {
|
case 'add value(s)': {
|
||||||
const combinedValues = new Set([
|
return {
|
||||||
...(state.values || []),
|
...state,
|
||||||
...action.payload,
|
values: state.values?.union(new Set(action.payload)),
|
||||||
]);
|
};
|
||||||
return { ...state, values: Array.from(combinedValues) };
|
|
||||||
}
|
}
|
||||||
case 'set value':
|
case 'set value':
|
||||||
return { ...state, value: action.payload };
|
return { ...state, value: action.payload };
|
||||||
@ -110,25 +129,35 @@ export const EditableConstraintWrapper = ({
|
|||||||
case 'toggle case sensitivity':
|
case 'toggle case sensitivity':
|
||||||
return { ...state, caseInsensitive: !state.inverted };
|
return { ...state, caseInsensitive: !state.inverted };
|
||||||
case 'remove value from list':
|
case 'remove value from list':
|
||||||
|
state.values?.delete(action.payload);
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
values: (state.values ?? []).filter(
|
values: state.values ?? new Set(),
|
||||||
(value) => value !== action.payload,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
case 'clear values':
|
case 'clear values':
|
||||||
return cleanConstraint({ ...state, values: [], value: '' });
|
return cleanConstraint({
|
||||||
|
...state,
|
||||||
|
values: new Set(),
|
||||||
|
value: '',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const [localConstraint, setLocalConstraint] = useState(
|
const [localConstraint, setLocalConstraint] = useState(() => {
|
||||||
cleanConstraint(constraint),
|
const withSet = {
|
||||||
);
|
...constraint,
|
||||||
|
values: new Set(constraint.values),
|
||||||
|
};
|
||||||
|
return cleanConstraint(withSet);
|
||||||
|
});
|
||||||
|
|
||||||
const updateConstraint = (action: ConstraintUpdateAction) => {
|
const updateConstraint = (action: ConstraintUpdateAction) => {
|
||||||
const nextState = constraintReducer(localConstraint, action);
|
const nextState = constraintReducer(localConstraint, action);
|
||||||
setLocalConstraint(nextState);
|
setLocalConstraint(nextState);
|
||||||
onAutoSave(nextState);
|
onAutoSave({
|
||||||
|
...nextState,
|
||||||
|
values: Array.from(nextState.values ?? []),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const { context } = useUnleashContext();
|
const { context } = useUnleashContext();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { Alert, Button, Checkbox, styled } from '@mui/material';
|
import { Alert, Button, Checkbox, styled } from '@mui/material';
|
||||||
import type { ILegalValue } from 'interfaces/context';
|
import type { ILegalValue } from 'interfaces/context';
|
||||||
@ -14,9 +14,9 @@ interface IRestrictiveLegalValuesProps {
|
|||||||
deletedLegalValues: ILegalValue[];
|
deletedLegalValues: ILegalValue[];
|
||||||
};
|
};
|
||||||
constraintValues: string[];
|
constraintValues: string[];
|
||||||
values: string[];
|
values: Set<string>;
|
||||||
addValues: (values: string[]) => void;
|
addValues: (values: string[]) => void;
|
||||||
removeValue: (values: string) => void;
|
removeValue: (value: string) => void;
|
||||||
clearAll: () => void;
|
clearAll: () => void;
|
||||||
beforeValues?: JSX.Element;
|
beforeValues?: JSX.Element;
|
||||||
}
|
}
|
||||||
@ -83,9 +83,6 @@ export const LegalValuesSelector = ({
|
|||||||
|
|
||||||
const filteredValues = filterLegalValues(legalValues, filter);
|
const filteredValues = filterLegalValues(legalValues, filter);
|
||||||
|
|
||||||
// Lazily initialise the values because there might be a lot of them.
|
|
||||||
const [valuesMap, setValuesMap] = useState(() => createValuesMap(values));
|
|
||||||
|
|
||||||
const cleanDeletedLegalValues = (constraintValues: string[]): string[] => {
|
const cleanDeletedLegalValues = (constraintValues: string[]): string[] => {
|
||||||
const deletedValuesSet = getLegalValueSet(deletedLegalValues);
|
const deletedValuesSet = getLegalValueSet(deletedLegalValues);
|
||||||
return (
|
return (
|
||||||
@ -99,29 +96,25 @@ export const LegalValuesSelector = ({
|
|||||||
deletedLegalValues,
|
deletedLegalValues,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
//todo: maybe move this up?
|
||||||
setValuesMap(createValuesMap(values));
|
// useEffect(() => {
|
||||||
}, [values, setValuesMap, createValuesMap]);
|
// if (illegalValues.length > 0) {
|
||||||
|
// removeValues(...illegalValues)
|
||||||
useEffect(() => {
|
// // todo: impl this
|
||||||
if (illegalValues.length > 0) {
|
// console.log('would clean deleted values here');
|
||||||
// todo: impl this
|
// // setvalues(cleandeletedlegalvalues(values));
|
||||||
console.log('would clean deleted values here');
|
// }
|
||||||
// setValues(cleanDeletedLegalValues(values));
|
// }, []);
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onChange = (legalValue: string) => {
|
const onChange = (legalValue: string) => {
|
||||||
if (valuesMap[legalValue]) {
|
if (values.has(legalValue)) {
|
||||||
removeValue(legalValue);
|
removeValue(legalValue);
|
||||||
} else {
|
} else {
|
||||||
addValues([legalValue]);
|
addValues([legalValue]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isAllSelected = legalValues.every((value) =>
|
const isAllSelected = legalValues.every((value) => values.has(value.value));
|
||||||
values.includes(value.value),
|
|
||||||
);
|
|
||||||
|
|
||||||
const onSelectAll = () => {
|
const onSelectAll = () => {
|
||||||
if (isAllSelected) {
|
if (isAllSelected) {
|
||||||
@ -185,7 +178,7 @@ export const LegalValuesSelector = ({
|
|||||||
filter={filter}
|
filter={filter}
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={Boolean(valuesMap[match.value])}
|
checked={Boolean(values.has(match.value))}
|
||||||
onChange={() => onChange(match.value)}
|
onChange={() => onChange(match.value)}
|
||||||
name='legal-value'
|
name='legal-value'
|
||||||
color='primary'
|
color='primary'
|
||||||
|
Loading…
Reference in New Issue
Block a user