mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-31 13:47:02 +02:00
Propagate to use IConstraintWithId everywhere until editor stops complaining.
This now passes checks to be "valid", but it doesn't do anything in and of itself. We still need to actually provide an id for these things to matter. I'm wondering whether it'd be better to make id mandatory on the regular constraints and add it on every incoming constraint.
This commit is contained in:
parent
4c358c88df
commit
6ff20cc7ff
@ -4,7 +4,7 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||
import useToast from 'hooks/useToast';
|
||||
import type { IFeatureStrategy } from 'interfaces/strategy';
|
||||
import type { IEditableStrategy, IFeatureStrategy } from 'interfaces/strategy';
|
||||
import { UPDATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
|
||||
import type { ISegment } from 'interfaces/segment';
|
||||
import { useFormErrors } from 'hooks/useFormErrors';
|
||||
@ -63,7 +63,7 @@ export const EditChange = ({
|
||||
|
||||
const constraintsWithId = addIdSymbolToConstraints(change.payload);
|
||||
|
||||
const [strategy, setStrategy] = useState<Partial<IFeatureStrategy>>({
|
||||
const [strategy, setStrategy] = useState<Partial<IEditableStrategy>>({
|
||||
...change.payload,
|
||||
constraints: constraintsWithId,
|
||||
});
|
||||
|
@ -7,12 +7,12 @@ import {
|
||||
type Theme,
|
||||
styled,
|
||||
} from '@mui/material';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
import { ConstraintAccordionViewBody } from './ConstraintAccordionViewBody/ConstraintAccordionViewBody.tsx';
|
||||
import { ConstraintAccordionViewHeader } from './ConstraintAccordionViewHeader/ConstraintAccordionViewHeader.tsx';
|
||||
import type { IConstraintWithId } from 'interfaces/strategy.ts';
|
||||
|
||||
interface IConstraintAccordionViewProps {
|
||||
constraint: IConstraint;
|
||||
constraint: IConstraintWithId;
|
||||
onUse?: () => void;
|
||||
sx?: SxProps<Theme>;
|
||||
disabled?: boolean;
|
||||
|
@ -1,21 +1,20 @@
|
||||
import type React from 'react';
|
||||
import { useEffect, useImperativeHandle } from 'react';
|
||||
import { useImperativeHandle } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import { styled } from '@mui/material';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
import type { IConstraint, IConstraintWithId } from 'interfaces/strategy';
|
||||
import produce from 'immer';
|
||||
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
|
||||
import { EditableConstraint } from 'component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint/EditableConstraint';
|
||||
import { createEmptyConstraint } from '../../../../utils/createEmptyConstraint.ts';
|
||||
import { constraintId } from 'constants/constraintId.ts';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
export interface IEditableConstraintsListRef {
|
||||
addConstraint?: (contextName: string) => void;
|
||||
}
|
||||
|
||||
export interface IEditableConstraintsListProps {
|
||||
constraints: IConstraint[];
|
||||
constraints: IConstraintWithId[];
|
||||
setConstraints: React.Dispatch<React.SetStateAction<IConstraint[]>>;
|
||||
}
|
||||
|
||||
@ -40,17 +39,6 @@ export const EditableConstraintsList = forwardRef<
|
||||
},
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
if (!constraints.every((constraint) => constraintId in constraint)) {
|
||||
setConstraints(
|
||||
constraints.map((constraint) => ({
|
||||
[constraintId]: uuidv4(),
|
||||
...constraint,
|
||||
})),
|
||||
);
|
||||
}
|
||||
}, [constraints, setConstraints]);
|
||||
|
||||
const onDelete = (index: number) => {
|
||||
setConstraints(
|
||||
produce((draft) => {
|
||||
@ -79,6 +67,7 @@ export const EditableConstraintsList = forwardRef<
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
IN THE constraints list. mapping: {JSON.stringify(constraints)}
|
||||
<ConstraintsList>
|
||||
{constraints.map((constraint, index) => (
|
||||
<EditableConstraint
|
||||
|
@ -2,7 +2,7 @@ import type React from 'react';
|
||||
import { forwardRef, useImperativeHandle, type RefObject } from 'react';
|
||||
import { Box, Button, styled, Typography } from '@mui/material';
|
||||
import Add from '@mui/icons-material/Add';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
import type { IConstraint, IConstraintWithId } from 'interfaces/strategy';
|
||||
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
||||
@ -15,8 +15,8 @@ import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashCon
|
||||
import { createEmptyConstraint } from 'utils/createEmptyConstraint.ts';
|
||||
|
||||
interface IConstraintAccordionListProps {
|
||||
constraints: IConstraint[];
|
||||
setConstraints?: React.Dispatch<React.SetStateAction<IConstraint[]>>;
|
||||
constraints: IConstraintWithId[];
|
||||
setConstraints?: React.Dispatch<React.SetStateAction<IConstraintWithId[]>>;
|
||||
showCreateButton?: boolean;
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ interface IConstraintAccordionListItemState {
|
||||
|
||||
const useConstraintAccordionList = (
|
||||
setConstraints:
|
||||
| React.Dispatch<React.SetStateAction<IConstraint[]>>
|
||||
| React.Dispatch<React.SetStateAction<IConstraintWithId[]>>
|
||||
| undefined,
|
||||
ref: React.RefObject<IConstraintAccordionListRef>,
|
||||
) => {
|
||||
@ -88,7 +88,7 @@ const useConstraintAccordionList = (
|
||||
export const FeatureStrategyConstraintAccordionList = forwardRef<
|
||||
IConstraintAccordionListRef | undefined,
|
||||
IConstraintAccordionListProps
|
||||
>(({ constraints, setConstraints, showCreateButton }, ref) => {
|
||||
>(({ constraints, setConstraints }, ref) => {
|
||||
const { onAdd, context } = useConstraintAccordionList(
|
||||
setConstraints,
|
||||
ref as RefObject<IConstraintAccordionListRef>,
|
||||
@ -101,8 +101,9 @@ export const FeatureStrategyConstraintAccordionList = forwardRef<
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
constraints are {JSON.stringify(constraints)}
|
||||
<ConditionallyRender
|
||||
condition={Boolean(showCreateButton && onAdd)}
|
||||
condition={Boolean(true)}
|
||||
show={
|
||||
<div>
|
||||
<StyledHelpIconBox>
|
||||
@ -128,13 +129,14 @@ export const FeatureStrategyConstraintAccordionList = forwardRef<
|
||||
}
|
||||
/>
|
||||
</StyledHelpIconBox>
|
||||
{setConstraints ? (
|
||||
|
||||
<fieldset disabled>
|
||||
<EditableConstraintsList
|
||||
ref={ref}
|
||||
setConstraints={setConstraints}
|
||||
setConstraints={() => {}}
|
||||
constraints={constraints}
|
||||
/>
|
||||
) : null}
|
||||
</fieldset>
|
||||
<Box
|
||||
sx={(theme) => ({
|
||||
marginTop: theme.spacing(2),
|
||||
@ -156,7 +158,7 @@ export const FeatureStrategyConstraintAccordionList = forwardRef<
|
||||
variant='outlined'
|
||||
color='primary'
|
||||
data-testid='ADD_CONSTRAINT_BUTTON'
|
||||
disabled={Boolean(limitReached)}
|
||||
disabled={Boolean(limitReached || !onAdd)}
|
||||
>
|
||||
Add constraint
|
||||
</Button>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { IConstraint, IFeatureStrategy } from 'interfaces/strategy';
|
||||
import type { IConstraintWithId, IEditableStrategy } from 'interfaces/strategy';
|
||||
import type React from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import {
|
||||
@ -11,9 +11,9 @@ import { FeatureStrategyConstraintAccordionList } from './FeatureStrategyConstra
|
||||
interface IFeatureStrategyConstraintsProps {
|
||||
projectId: string;
|
||||
environmentId: string;
|
||||
strategy: Partial<IFeatureStrategy>;
|
||||
strategy: Partial<IEditableStrategy>;
|
||||
setStrategy: React.Dispatch<
|
||||
React.SetStateAction<Partial<IFeatureStrategy>>
|
||||
React.SetStateAction<Partial<IEditableStrategy>>
|
||||
>;
|
||||
}
|
||||
|
||||
@ -53,7 +53,9 @@ export const FeatureStrategyConstraints = ({
|
||||
|
||||
const constraints = strategy.constraints || [];
|
||||
|
||||
const setConstraints = (value: React.SetStateAction<IConstraint[]>) => {
|
||||
const setConstraints = (
|
||||
value: React.SetStateAction<IConstraintWithId[]>,
|
||||
) => {
|
||||
setStrategy((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
|
@ -5,11 +5,11 @@ import {
|
||||
areConstraintsEqual,
|
||||
getConstraintKey,
|
||||
} from './useRecentlyUsedConstraints.ts';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
import type { IConstraintWithId } from 'interfaces/strategy.ts';
|
||||
|
||||
type IRecentlyUsedConstraintsProps = {
|
||||
setConstraints?: React.Dispatch<React.SetStateAction<IConstraint[]>>;
|
||||
constraints?: IConstraint[];
|
||||
setConstraints?: React.Dispatch<React.SetStateAction<IConstraintWithId[]>>;
|
||||
constraints?: IConstraintWithId[];
|
||||
};
|
||||
|
||||
const StyledContainer = styled('div')(({ theme }) => ({
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useLocalStorageState } from 'hooks/useLocalStorageState';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
import type { IConstraint, IConstraintWithId } from 'interfaces/strategy';
|
||||
|
||||
const hashString = (str: string): number => {
|
||||
let hash = 0;
|
||||
@ -41,14 +41,14 @@ export const areConstraintsEqual = (
|
||||
};
|
||||
|
||||
export const useRecentlyUsedConstraints = (
|
||||
initialItems: IConstraint[] = [],
|
||||
initialItems: IConstraintWithId[] = [],
|
||||
) => {
|
||||
const [items, setItems] = useLocalStorageState<IConstraint[]>(
|
||||
const [items, setItems] = useLocalStorageState<IConstraintWithId[]>(
|
||||
'recently-used-constraints',
|
||||
initialItems,
|
||||
);
|
||||
|
||||
const addItem = (newItem: IConstraint | IConstraint[]) => {
|
||||
const addItem = (newItem: IConstraintWithId | IConstraintWithId[]) => {
|
||||
setItems((prevItems) => {
|
||||
const itemsToAdd = Array.isArray(newItem) ? newItem : [newItem];
|
||||
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
Link,
|
||||
} from '@mui/material';
|
||||
import type {
|
||||
IFeatureStrategy,
|
||||
IEditableStrategy,
|
||||
IFeatureStrategyParameters,
|
||||
IStrategyParameter,
|
||||
} from 'interfaces/strategy';
|
||||
@ -57,9 +57,9 @@ interface IFeatureStrategyFormProps {
|
||||
onCancel?: () => void;
|
||||
loading: boolean;
|
||||
isChangeRequest: boolean;
|
||||
strategy: Partial<IFeatureStrategy>;
|
||||
strategy: Partial<IEditableStrategy>;
|
||||
setStrategy: React.Dispatch<
|
||||
React.SetStateAction<Partial<IFeatureStrategy>>
|
||||
React.SetStateAction<Partial<IEditableStrategy>>
|
||||
>;
|
||||
segments: ISegment[];
|
||||
setSegments: React.Dispatch<React.SetStateAction<ISegment[]>>;
|
||||
|
@ -1,4 +1,8 @@
|
||||
import type { IFeatureStrategy, IStrategy } from 'interfaces/strategy';
|
||||
import type {
|
||||
IEditableStrategy,
|
||||
IFeatureStrategy,
|
||||
IStrategy,
|
||||
} from 'interfaces/strategy';
|
||||
import DefaultStrategy from 'component/feature/StrategyTypes/DefaultStrategy/DefaultStrategy';
|
||||
import FlexibleStrategy from 'component/feature/StrategyTypes/FlexibleStrategy/FlexibleStrategy';
|
||||
import GeneralStrategy from 'component/feature/StrategyTypes/GeneralStrategy/GeneralStrategy';
|
||||
@ -12,7 +16,7 @@ interface IFeatureStrategyTypeProps {
|
||||
strategy: Partial<IFeatureStrategy>;
|
||||
strategyDefinition: IStrategy;
|
||||
setStrategy: React.Dispatch<
|
||||
React.SetStateAction<Partial<IFeatureStrategy>>
|
||||
React.SetStateAction<Partial<IEditableStrategy>>
|
||||
>;
|
||||
validateParameter: (name: string, value: string) => boolean;
|
||||
errors: IFormErrors;
|
||||
|
@ -8,7 +8,7 @@ import { UPDATE_FEATURE_ENVIRONMENT_VARIANTS } from '../../providers/AccessProvi
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { WeightType } from '../../../constants/variantTypes.ts';
|
||||
import { Box, styled, Typography, useTheme, Alert } from '@mui/material';
|
||||
import type { IFeatureStrategy } from 'interfaces/strategy';
|
||||
import type { IEditableStrategy, IFeatureStrategy } from 'interfaces/strategy';
|
||||
import { VariantsSplitPreview } from 'component/common/VariantsSplitPreview/VariantsSplitPreview';
|
||||
import { HelpIcon } from 'component/common/HelpIcon/HelpIcon';
|
||||
import { StrategyVariantsUpgradeAlert } from 'component/common/StrategyVariantsUpgradeAlert/StrategyVariantsUpgradeAlert';
|
||||
@ -30,7 +30,7 @@ const StyledHelpIconBox = styled(Box)(({ theme }) => ({
|
||||
|
||||
export const NewStrategyVariants: FC<{
|
||||
setStrategy: React.Dispatch<
|
||||
React.SetStateAction<Partial<IFeatureStrategy>>
|
||||
React.SetStateAction<Partial<IEditableStrategy>>
|
||||
>;
|
||||
strategy: Partial<IFeatureStrategy>;
|
||||
projectId: string;
|
||||
|
@ -3,6 +3,7 @@ import { formatApiPath } from 'utils/formatPath';
|
||||
import handleErrorResponses from '../httpErrorResponseHandler.js';
|
||||
import type { ChangeRequestType } from 'component/changeRequest/changeRequest.types';
|
||||
|
||||
// we get constraints here
|
||||
export const useChangeRequest = (projectId: string, id: string) => {
|
||||
const { data, error, mutate } = useSWR<ChangeRequestType>(
|
||||
formatApiPath(`api/admin/projects/${projectId}/change-requests/${id}`),
|
||||
|
@ -68,6 +68,10 @@ export interface IConstraint {
|
||||
[constraintId]?: string;
|
||||
}
|
||||
|
||||
export interface IEditableStrategy extends IFeatureStrategy {
|
||||
constraints: IConstraintWithId[];
|
||||
}
|
||||
|
||||
export interface IConstraintWithId extends IConstraint {
|
||||
[constraintId]: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user