mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-09 13:47:13 +02:00
move legal/deleted values up
This commit is contained in:
parent
4d4a6b422a
commit
7a25c2e23f
@ -6,7 +6,10 @@ import {
|
||||
} from 'component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/useConstraintInput/useConstraintInput';
|
||||
import { stringOperators, type Operator } from 'constants/operators';
|
||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||
import type { IUnleashContextDefinition } from 'interfaces/context';
|
||||
import type {
|
||||
ILegalValue,
|
||||
IUnleashContextDefinition,
|
||||
} from 'interfaces/context';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
import { useMemo, useRef, type FC } from 'react';
|
||||
import { operatorsForContext } from 'utils/operatorsForContext';
|
||||
@ -24,7 +27,6 @@ import { ReactComponent as NotEqualsIcon } from 'assets/icons/constraint-not-equ
|
||||
import { AddSingleValueWidget } from './AddSingleValueWidget';
|
||||
import { ConstraintDateInput } from './ConstraintDateInput';
|
||||
import { LegalValuesSelector } from './LegalValuesSelector';
|
||||
import { resolveLegalValues } from './resolve-legal-values';
|
||||
import { constraintValidator } from './constraint-validator';
|
||||
|
||||
const Container = styled('article')(({ theme }) => ({
|
||||
@ -186,14 +188,17 @@ type Props = {
|
||||
contextDefinition: Pick<IUnleashContextDefinition, 'legalValues'>;
|
||||
constraintValues: string[];
|
||||
updateConstraint: (action: ConstraintUpdateAction) => void;
|
||||
deletedLegalValues?: Set<string>;
|
||||
legalValues?: ILegalValue[];
|
||||
};
|
||||
|
||||
export const EditableConstraint: FC<Props> = ({
|
||||
localConstraint,
|
||||
onDelete,
|
||||
contextDefinition,
|
||||
constraintValues,
|
||||
updateConstraint,
|
||||
deletedLegalValues,
|
||||
legalValues,
|
||||
}) => {
|
||||
const { input } = useConstraintInput({
|
||||
contextDefinition,
|
||||
@ -391,11 +396,6 @@ export const EditableConstraint: FC<Props> = ({
|
||||
{inputType.input === 'legal values' ? (
|
||||
<LegalValuesContainer>
|
||||
<LegalValuesSelector
|
||||
data={resolveLegalValues(
|
||||
constraintValues,
|
||||
contextDefinition.legalValues,
|
||||
)}
|
||||
constraintValues={constraintValues}
|
||||
values={localConstraint.values || new Set()}
|
||||
clearAll={() =>
|
||||
updateConstraint({
|
||||
@ -414,6 +414,8 @@ export const EditableConstraint: FC<Props> = ({
|
||||
payload: value,
|
||||
})
|
||||
}
|
||||
deletedLegalValues={deletedLegalValues}
|
||||
legalValues={legalValues ?? []}
|
||||
/>
|
||||
</LegalValuesContainer>
|
||||
) : null}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||
import type { IUnleashContextDefinition } from 'interfaces/context';
|
||||
@ -72,9 +72,43 @@ export const EditableConstraintWrapper = ({
|
||||
onDelete,
|
||||
onAutoSave,
|
||||
}: IConstraintAccordionEditProps) => {
|
||||
const [localConstraint, setLocalConstraint] = useState(() => {
|
||||
const withSet = {
|
||||
...constraint,
|
||||
values: new Set(constraint.values),
|
||||
};
|
||||
return cleanConstraint(withSet);
|
||||
});
|
||||
|
||||
const { context } = useUnleashContext();
|
||||
const [contextDefinition, setContextDefinition] = useState(
|
||||
resolveContextDefinition(context, localConstraint.contextName),
|
||||
);
|
||||
|
||||
const deletedLegalValues = useMemo(() => {
|
||||
if (
|
||||
contextDefinition.legalValues?.length &&
|
||||
constraint.values?.length
|
||||
) {
|
||||
const currentLegalValues = new Set(
|
||||
contextDefinition.legalValues.map(({ value }) => value),
|
||||
);
|
||||
const deletedValues = new Set(constraint.values).difference(
|
||||
currentLegalValues,
|
||||
);
|
||||
|
||||
return deletedValues;
|
||||
}
|
||||
return undefined;
|
||||
}, [
|
||||
JSON.stringify(contextDefinition.legalValues),
|
||||
JSON.stringify(constraint.values),
|
||||
]);
|
||||
|
||||
const constraintReducer = (
|
||||
state: ConstraintWithValueSet,
|
||||
action: ConstraintUpdateAction,
|
||||
deletedLegalValues?: Set<string>,
|
||||
): ConstraintWithValueSet => {
|
||||
switch (action.type) {
|
||||
case 'set context field':
|
||||
@ -127,9 +161,15 @@ export const EditableConstraintWrapper = ({
|
||||
value: '',
|
||||
});
|
||||
case 'add value(s)': {
|
||||
const combinedValues = state.values?.union(
|
||||
new Set(action.payload),
|
||||
);
|
||||
const filteredValues = deletedLegalValues
|
||||
? combinedValues?.difference(deletedLegalValues)
|
||||
: deletedLegalValues;
|
||||
return {
|
||||
...state,
|
||||
values: state.values?.union(new Set(action.payload)),
|
||||
values: filteredValues,
|
||||
};
|
||||
}
|
||||
case 'set value':
|
||||
@ -153,21 +193,12 @@ export const EditableConstraintWrapper = ({
|
||||
}
|
||||
};
|
||||
|
||||
const [localConstraint, setLocalConstraint] = useState(() => {
|
||||
const withSet = {
|
||||
...constraint,
|
||||
values: new Set(constraint.values),
|
||||
};
|
||||
return cleanConstraint(withSet);
|
||||
});
|
||||
|
||||
const { context } = useUnleashContext();
|
||||
const [contextDefinition, setContextDefinition] = useState(
|
||||
resolveContextDefinition(context, localConstraint.contextName),
|
||||
);
|
||||
|
||||
const updateConstraint = (action: ConstraintUpdateAction) => {
|
||||
const nextState = constraintReducer(localConstraint, action);
|
||||
const nextState = constraintReducer(
|
||||
localConstraint,
|
||||
action,
|
||||
deletedLegalValues,
|
||||
);
|
||||
const contextFieldHasChanged =
|
||||
localConstraint.contextName !== nextState.contextName;
|
||||
|
||||
@ -191,6 +222,8 @@ export const EditableConstraintWrapper = ({
|
||||
constraintValues={constraint?.values || []}
|
||||
contextDefinition={contextDefinition}
|
||||
updateConstraint={updateConstraint}
|
||||
deletedLegalValues={deletedLegalValues}
|
||||
legalValues={contextDefinition.legalValues}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -1,54 +1,21 @@
|
||||
import { useState } from 'react';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { Alert, Button, Checkbox, styled } from '@mui/material';
|
||||
import type { ILegalValue } from 'interfaces/context';
|
||||
import {
|
||||
filterLegalValues,
|
||||
LegalValueLabel,
|
||||
} from 'component/common/NewConstraintAccordion/ConstraintAccordionEdit/ConstraintAccordionEditBody/LegalValueLabel/LegalValueLabel';
|
||||
import { ConstraintValueSearch } from './ConstraintValueSearch';
|
||||
import type { ILegalValue } from 'interfaces/context';
|
||||
|
||||
interface IRestrictiveLegalValuesProps {
|
||||
data: {
|
||||
legalValues: ILegalValue[];
|
||||
deletedLegalValues: ILegalValue[];
|
||||
};
|
||||
constraintValues: string[];
|
||||
values: Set<string>;
|
||||
addValues: (values: string[]) => void;
|
||||
removeValue: (value: string) => void;
|
||||
clearAll: () => void;
|
||||
beforeValues?: JSX.Element;
|
||||
deletedLegalValues?: Set<string>;
|
||||
legalValues: ILegalValue[];
|
||||
}
|
||||
|
||||
interface IValuesMap {
|
||||
[key: string]: boolean;
|
||||
}
|
||||
|
||||
const createValuesMap = (values: string[]): IValuesMap => {
|
||||
return values.reduce((result: IValuesMap, currentValue: string) => {
|
||||
if (!result[currentValue]) {
|
||||
result[currentValue] = true;
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
};
|
||||
|
||||
export const getLegalValueSet = (values: ILegalValue[]) => {
|
||||
return new Set(values.map(({ value }) => value));
|
||||
};
|
||||
|
||||
export const getIllegalValues = (
|
||||
constraintValues: string[],
|
||||
deletedLegalValues: ILegalValue[],
|
||||
) => {
|
||||
const deletedValuesSet = getLegalValueSet(deletedLegalValues);
|
||||
|
||||
return constraintValues.filter(
|
||||
(value) => value && deletedValuesSet.has(value),
|
||||
);
|
||||
};
|
||||
|
||||
const StyledValuesContainer = styled('div')(({ theme }) => ({
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',
|
||||
@ -71,41 +38,17 @@ const LegalValuesSelectorWidget = styled('article')(({ theme }) => ({
|
||||
}));
|
||||
|
||||
export const LegalValuesSelector = ({
|
||||
data,
|
||||
legalValues,
|
||||
values,
|
||||
addValues,
|
||||
removeValue,
|
||||
clearAll,
|
||||
constraintValues,
|
||||
deletedLegalValues,
|
||||
}: IRestrictiveLegalValuesProps) => {
|
||||
const [filter, setFilter] = useState('');
|
||||
const { legalValues, deletedLegalValues } = data;
|
||||
|
||||
const filteredValues = filterLegalValues(legalValues, filter);
|
||||
|
||||
const cleanDeletedLegalValues = (constraintValues: string[]): string[] => {
|
||||
const deletedValuesSet = getLegalValueSet(deletedLegalValues);
|
||||
return (
|
||||
constraintValues?.filter((value) => !deletedValuesSet.has(value)) ||
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
const illegalValues = getIllegalValues(
|
||||
constraintValues,
|
||||
deletedLegalValues,
|
||||
);
|
||||
|
||||
//todo: maybe move this up?
|
||||
// useEffect(() => {
|
||||
// if (illegalValues.length > 0) {
|
||||
// removeValues(...illegalValues)
|
||||
// // todo: impl this
|
||||
// console.log('would clean deleted values here');
|
||||
// // setvalues(cleandeletedlegalvalues(values));
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
const onChange = (legalValue: string) => {
|
||||
if (values.has(legalValue)) {
|
||||
removeValue(legalValue);
|
||||
@ -137,22 +80,18 @@ export const LegalValuesSelector = ({
|
||||
|
||||
return (
|
||||
<LegalValuesSelectorWidget>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(illegalValues && illegalValues.length > 0)}
|
||||
show={
|
||||
<Alert severity='warning'>
|
||||
This constraint is using legal values that have been
|
||||
deleted as valid options. If you save changes on this
|
||||
constraint and then save the strategy the following
|
||||
values will be removed:
|
||||
<ul>
|
||||
{illegalValues?.map((value) => (
|
||||
<li key={value}>{value}</li>
|
||||
))}
|
||||
</ul>
|
||||
</Alert>
|
||||
}
|
||||
/>
|
||||
{deletedLegalValues?.size ? (
|
||||
<Alert severity='warning'>
|
||||
This constraint is using legal values that have been deleted
|
||||
as valid options. If you save changes on this constraint and
|
||||
then save the strategy the following values will be removed:
|
||||
<ul>
|
||||
{[...deletedLegalValues].map((value) => (
|
||||
<li key={value}>{value}</li>
|
||||
))}
|
||||
</ul>
|
||||
</Alert>
|
||||
) : null}
|
||||
<p>Select values from a predefined set</p>
|
||||
<Row>
|
||||
<ConstraintValueSearch
|
||||
@ -182,9 +121,7 @@ export const LegalValuesSelector = ({
|
||||
onChange={() => onChange(match.value)}
|
||||
name='legal-value'
|
||||
color='primary'
|
||||
disabled={deletedLegalValues
|
||||
.map(({ value }) => value)
|
||||
.includes(match.value)}
|
||||
disabled={deletedLegalValues?.has(match.value)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user