mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-31 13:47:02 +02:00
more cleanup jobs
This commit is contained in:
parent
5403ac0751
commit
5a793f9c3e
@ -23,7 +23,6 @@ const StyledWrapper = styled('div')(({ theme }) => ({
|
||||
|
||||
/**
|
||||
* @deprecated use `component/feature/FeatureStrategy/FeatureStrategyConstraints/ConstraintDateInput.tsx`
|
||||
* Remove with flag `addEditStrategy`
|
||||
*/
|
||||
export const DateSingleValue = ({
|
||||
setValue,
|
||||
|
@ -1,27 +1,21 @@
|
||||
import type {
|
||||
ILegalValue,
|
||||
IUnleashContextDefinition,
|
||||
} from 'interfaces/context';
|
||||
import type { IUnleashContextDefinition } from 'interfaces/context';
|
||||
import type { IConstraint } from 'interfaces/strategy';
|
||||
import { DateSingleValue } from '../DateSingleValue/DateSingleValue.tsx';
|
||||
import { FreeTextInput } from '../FreeTextInput/FreeTextInput.tsx';
|
||||
import { RestrictiveLegalValues } from '../RestrictiveLegalValues/RestrictiveLegalValues.tsx';
|
||||
import { SingleLegalValue } from '../SingleLegalValue/SingleLegalValue.tsx';
|
||||
import { SingleValue } from '../SingleValue/SingleValue.tsx';
|
||||
import {
|
||||
IN_OPERATORS_LEGAL_VALUES,
|
||||
STRING_OPERATORS_FREETEXT,
|
||||
STRING_OPERATORS_LEGAL_VALUES,
|
||||
SEMVER_OPERATORS_SINGLE_VALUE,
|
||||
NUM_OPERATORS_LEGAL_VALUES,
|
||||
NUM_OPERATORS_SINGLE_VALUE,
|
||||
SEMVER_OPERATORS_LEGAL_VALUES,
|
||||
DATE_OPERATORS_SINGLE_VALUE,
|
||||
IN_OPERATORS_FREETEXT,
|
||||
type Input,
|
||||
} from '../useConstraintInput/useConstraintInput.tsx';
|
||||
import type React from 'react';
|
||||
|
||||
type ActionFilterItemInput =
|
||||
| typeof STRING_OPERATORS_FREETEXT
|
||||
| typeof SEMVER_OPERATORS_SINGLE_VALUE
|
||||
| typeof NUM_OPERATORS_SINGLE_VALUE
|
||||
| typeof IN_OPERATORS_FREETEXT;
|
||||
|
||||
interface IResolveInputProps {
|
||||
contextDefinition: Pick<IUnleashContextDefinition, 'legalValues'>;
|
||||
localConstraint: Pick<IConstraint, 'value' | 'values'>;
|
||||
@ -32,38 +26,12 @@ interface IResolveInputProps {
|
||||
setValuesWithRecord: (values: string[]) => void;
|
||||
setError: React.Dispatch<React.SetStateAction<string>>;
|
||||
removeValue: (index: number) => void;
|
||||
input: Input;
|
||||
input: ActionFilterItemInput;
|
||||
error: string;
|
||||
}
|
||||
|
||||
const resolveLegalValues = (
|
||||
values: IConstraint['values'],
|
||||
legalValues: IUnleashContextDefinition['legalValues'],
|
||||
): { legalValues: ILegalValue[]; deletedLegalValues: ILegalValue[] } => {
|
||||
if (legalValues?.length === 0) {
|
||||
return {
|
||||
legalValues: [],
|
||||
deletedLegalValues: [],
|
||||
};
|
||||
}
|
||||
|
||||
const deletedLegalValues = (values || [])
|
||||
.filter(
|
||||
(value) =>
|
||||
!(legalValues || []).some(
|
||||
({ value: legalValue }) => legalValue === value,
|
||||
),
|
||||
)
|
||||
.map((v) => ({ value: v, description: '' }));
|
||||
|
||||
return {
|
||||
legalValues: legalValues || [],
|
||||
deletedLegalValues,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated; remove with `addEditStrategy` flag. Need an input? Prefer using specific input components.
|
||||
* @deprecated; Need an input? Prefer using specific input components.
|
||||
*
|
||||
* For the case of `ProjectActionsFilterItem.tsx`: it already excludes legal
|
||||
* values and date operators. This leaves only free text and single value
|
||||
@ -71,12 +39,8 @@ const resolveLegalValues = (
|
||||
*/
|
||||
export const ResolveInput = ({
|
||||
input,
|
||||
contextDefinition,
|
||||
constraintValues,
|
||||
constraintValue,
|
||||
localConstraint,
|
||||
setValue,
|
||||
setValues,
|
||||
setValuesWithRecord,
|
||||
setError,
|
||||
removeValue,
|
||||
@ -84,72 +48,8 @@ export const ResolveInput = ({
|
||||
}: IResolveInputProps) => {
|
||||
const resolveInput = () => {
|
||||
switch (input) {
|
||||
case IN_OPERATORS_LEGAL_VALUES:
|
||||
case STRING_OPERATORS_LEGAL_VALUES:
|
||||
return (
|
||||
<RestrictiveLegalValues
|
||||
data={resolveLegalValues(
|
||||
constraintValues,
|
||||
contextDefinition.legalValues,
|
||||
)}
|
||||
constraintValues={constraintValues}
|
||||
values={localConstraint.values || []}
|
||||
setValuesWithRecord={setValuesWithRecord}
|
||||
setValues={setValues}
|
||||
error={error}
|
||||
setError={setError}
|
||||
/>
|
||||
);
|
||||
case NUM_OPERATORS_LEGAL_VALUES:
|
||||
return (
|
||||
<>
|
||||
<SingleLegalValue
|
||||
data={resolveLegalValues(
|
||||
[constraintValue],
|
||||
contextDefinition.legalValues,
|
||||
)}
|
||||
setValue={setValue}
|
||||
value={localConstraint.value}
|
||||
constraintValue={constraintValue}
|
||||
type='number'
|
||||
legalValues={
|
||||
contextDefinition.legalValues?.filter(
|
||||
(legalValue) => Number(legalValue.value),
|
||||
) || []
|
||||
}
|
||||
error={error}
|
||||
setError={setError}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
case SEMVER_OPERATORS_LEGAL_VALUES:
|
||||
return (
|
||||
<>
|
||||
<SingleLegalValue
|
||||
data={resolveLegalValues(
|
||||
[constraintValue],
|
||||
contextDefinition.legalValues,
|
||||
)}
|
||||
setValue={setValue}
|
||||
value={localConstraint.value}
|
||||
constraintValue={constraintValue}
|
||||
type='semver'
|
||||
legalValues={contextDefinition.legalValues || []}
|
||||
error={error}
|
||||
setError={setError}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
case DATE_OPERATORS_SINGLE_VALUE:
|
||||
return (
|
||||
<DateSingleValue
|
||||
value={localConstraint.value}
|
||||
setValue={setValue}
|
||||
error={error}
|
||||
setError={setError}
|
||||
/>
|
||||
);
|
||||
case IN_OPERATORS_FREETEXT:
|
||||
case STRING_OPERATORS_FREETEXT:
|
||||
return (
|
||||
<FreeTextInput
|
||||
values={localConstraint.values || []}
|
||||
@ -159,18 +59,6 @@ export const ResolveInput = ({
|
||||
setError={setError}
|
||||
/>
|
||||
);
|
||||
case STRING_OPERATORS_FREETEXT:
|
||||
return (
|
||||
<>
|
||||
<FreeTextInput
|
||||
values={localConstraint.values || []}
|
||||
removeValue={removeValue}
|
||||
setValues={setValuesWithRecord}
|
||||
error={error}
|
||||
setError={setError}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
case NUM_OPERATORS_SINGLE_VALUE:
|
||||
return (
|
||||
<SingleValue
|
||||
|
@ -65,7 +65,7 @@ type Validator =
|
||||
| 'DATE_VALIDATOR';
|
||||
|
||||
/**
|
||||
* @deprecated; remove with `addEditStrategy` flag. This component requires a lot of state and mixes many components. Better off using dedicated pieces where you need them.
|
||||
* @deprecated; This component requires a lot of state and mixes many components. Better off using dedicated pieces where you need them.
|
||||
*/
|
||||
export const useConstraintInput = ({
|
||||
contextDefinition,
|
||||
|
@ -5,12 +5,12 @@ import { styled } from '@mui/material';
|
||||
import type { IConstraint } 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 {
|
||||
constraintId,
|
||||
createEmptyConstraint,
|
||||
} from 'component/common/LegacyConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
|
||||
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
|
||||
import { EditableConstraint } from 'component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraint/EditableConstraint';
|
||||
} from 'utils/createEmptyConstraint';
|
||||
export interface IEditableConstraintsListRef {
|
||||
addConstraint?: (contextName: string) => void;
|
||||
}
|
||||
|
145
frontend/src/component/common/SegmentItem/SegmentItem.tsx
Normal file
145
frontend/src/component/common/SegmentItem/SegmentItem.tsx
Normal file
@ -0,0 +1,145 @@
|
||||
import { useId, useMemo, useState, type FC } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import type { ISegment } from 'interfaces/segment';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Button,
|
||||
styled,
|
||||
} from '@mui/material';
|
||||
import { StrategyEvaluationItem } from 'component/common/ConstraintsList/StrategyEvaluationItem/StrategyEvaluationItem';
|
||||
import { objectId } from 'utils/objectId';
|
||||
import {
|
||||
ConstraintListItem,
|
||||
ConstraintsList,
|
||||
} from 'component/common/ConstraintsList/ConstraintsList';
|
||||
import { ConstraintAccordionView } from '../NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView.tsx';
|
||||
|
||||
type SegmentItemProps = {
|
||||
segment: Partial<ISegment>;
|
||||
isExpanded?: boolean;
|
||||
disabled?: boolean | null;
|
||||
constraintList?: JSX.Element;
|
||||
headerContent?: JSX.Element;
|
||||
};
|
||||
|
||||
const StyledConstraintListItem = styled(ConstraintListItem)(() => ({
|
||||
padding: 0,
|
||||
}));
|
||||
|
||||
const StyledAccordion = styled(Accordion)(() => ({
|
||||
boxShadow: 'none',
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
'::before': {
|
||||
// MUI separator between accordions
|
||||
display: 'none',
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
|
||||
fontSize: theme.typography.body2.fontSize,
|
||||
minHeight: 'unset',
|
||||
':focus-within': {
|
||||
backgroundColor: 'inherit',
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledAccordionDetails = styled(AccordionDetails)(({ theme }) => ({
|
||||
padding: theme.spacing(0.5, 3, 2.5),
|
||||
}));
|
||||
|
||||
const StyledLink = styled(Link)(({ theme }) => ({
|
||||
textDecoration: 'none',
|
||||
paddingRight: theme.spacing(0.5),
|
||||
'&:hover': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledActionsContainer = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginLeft: 'auto',
|
||||
}));
|
||||
|
||||
const StyledButton = styled(Button)(({ theme }) => ({
|
||||
fontSize: theme.typography.body2.fontSize,
|
||||
}));
|
||||
|
||||
const StyledNoConstraintsText = styled('p')(({ theme }) => ({
|
||||
fontSize: theme.typography.body2.fontSize,
|
||||
color: theme.palette.text.secondary,
|
||||
}));
|
||||
|
||||
export const SegmentItem: FC<SegmentItemProps> = ({
|
||||
segment,
|
||||
isExpanded,
|
||||
headerContent,
|
||||
constraintList,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(isExpanded || false);
|
||||
const segmentDetailsId = useId();
|
||||
|
||||
const constraints = useMemo(() => {
|
||||
if (constraintList) {
|
||||
return constraintList;
|
||||
}
|
||||
|
||||
if (segment.constraints?.length) {
|
||||
return (
|
||||
<ConstraintsList>
|
||||
{segment.constraints.map((constraint, index) => (
|
||||
<ConstraintAccordionView
|
||||
key={`${objectId(constraint)}-${index}`}
|
||||
constraint={constraint}
|
||||
/>
|
||||
))}
|
||||
</ConstraintsList>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledNoConstraintsText>
|
||||
This segment has no constraints.
|
||||
</StyledNoConstraintsText>
|
||||
);
|
||||
}, [constraintList, segment.constraints]);
|
||||
|
||||
return (
|
||||
<StyledConstraintListItem>
|
||||
<StyledAccordion
|
||||
expanded={isOpen}
|
||||
disableGutters
|
||||
TransitionProps={{ mountOnEnter: true, unmountOnExit: true }}
|
||||
>
|
||||
<StyledAccordionSummary
|
||||
id={`segment-accordion-${segment.id}`}
|
||||
tabIndex={-1}
|
||||
aria-controls={segmentDetailsId}
|
||||
>
|
||||
<StrategyEvaluationItem type='Segment'>
|
||||
<StyledLink to={`/segments/edit/${segment.id}`}>
|
||||
{segment.name}
|
||||
</StyledLink>
|
||||
</StrategyEvaluationItem>
|
||||
{headerContent ? headerContent : null}
|
||||
{!isExpanded ? (
|
||||
<StyledActionsContainer>
|
||||
<StyledButton
|
||||
aria-controls={segmentDetailsId}
|
||||
size='small'
|
||||
variant='outlined'
|
||||
onClick={() => setIsOpen((value) => !value)}
|
||||
>
|
||||
{isOpen ? 'Close preview' : 'Preview'}
|
||||
</StyledButton>
|
||||
</StyledActionsContainer>
|
||||
) : null}
|
||||
</StyledAccordionSummary>
|
||||
<StyledAccordionDetails>{constraints}</StyledAccordionDetails>
|
||||
</StyledAccordion>
|
||||
</StyledConstraintListItem>
|
||||
);
|
||||
};
|
@ -28,13 +28,14 @@ import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequ
|
||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
|
||||
import { FeatureStrategyForm } from '../FeatureStrategyForm/FeatureStrategyForm.tsx';
|
||||
import { NewStrategyVariants } from 'component/feature/StrategyTypes/NewStrategyVariants';
|
||||
import { constraintId } from 'component/common/LegacyConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
|
||||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { useScheduledChangeRequestsWithStrategy } from 'hooks/api/getters/useScheduledChangeRequestsWithStrategy/useScheduledChangeRequestsWithStrategy';
|
||||
import {
|
||||
getChangeRequestConflictCreatedData,
|
||||
getChangeRequestConflictCreatedDataFromScheduleData,
|
||||
} from './change-request-conflict-data.ts';
|
||||
import { constraintId } from 'utils/createEmptyConstraint.ts';
|
||||
|
||||
const useTitleTracking = () => {
|
||||
const [previousTitle, setPreviousTitle] = useState<string>('');
|
||||
|
Loading…
Reference in New Issue
Block a user