mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-17 13:46:47 +02:00
feat: separate constraint edit/view screens (#9836)
Separating constraing edit and view screens. Next PR is to start using these.
This commit is contained in:
parent
d24bcff404
commit
3774cf8b87
@ -0,0 +1,50 @@
|
|||||||
|
import type React from 'react';
|
||||||
|
import { useImperativeHandle } from 'react';
|
||||||
|
import type { IConstraint } from 'interfaces/strategy';
|
||||||
|
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||||
|
import { useWeakMap } from 'hooks/useWeakMap';
|
||||||
|
import { createEmptyConstraint } from 'component/common/LegacyConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
|
||||||
|
|
||||||
|
export interface IConstraintsListProps {
|
||||||
|
constraints: IConstraint[];
|
||||||
|
setConstraints?: React.Dispatch<React.SetStateAction<IConstraint[]>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IConstraintsListRef {
|
||||||
|
addConstraint?: (contextName: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IConstraintsListItemState {
|
||||||
|
new?: boolean;
|
||||||
|
editing?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useConstraintsList = (
|
||||||
|
setConstraints:
|
||||||
|
| React.Dispatch<React.SetStateAction<IConstraint[]>>
|
||||||
|
| undefined,
|
||||||
|
ref: React.RefObject<IConstraintsListRef>,
|
||||||
|
) => {
|
||||||
|
const state = useWeakMap<IConstraint, IConstraintsListItemState>();
|
||||||
|
const { context } = useUnleashContext();
|
||||||
|
|
||||||
|
const addConstraint =
|
||||||
|
setConstraints &&
|
||||||
|
((contextName: string) => {
|
||||||
|
const constraint = createEmptyConstraint(contextName);
|
||||||
|
state.set(constraint, { editing: true, new: true });
|
||||||
|
setConstraints((prev) => [...prev, constraint]);
|
||||||
|
});
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
addConstraint,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const onAdd =
|
||||||
|
addConstraint &&
|
||||||
|
(() => {
|
||||||
|
addConstraint(context[0].name);
|
||||||
|
});
|
||||||
|
|
||||||
|
return { onAdd, state, context };
|
||||||
|
};
|
@ -0,0 +1,101 @@
|
|||||||
|
import { forwardRef } from 'react';
|
||||||
|
import { styled } from '@mui/material';
|
||||||
|
import type { IConstraint } from 'interfaces/strategy';
|
||||||
|
import produce from 'immer';
|
||||||
|
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||||
|
import { useWeakMap } from 'hooks/useWeakMap';
|
||||||
|
import { constraintId } from 'component/common/LegacyConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
|
||||||
|
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
|
||||||
|
import { EditableConstraintWrapper } from 'component/feature/FeatureStrategy/FeatureStrategyConstraints/EditableConstraintWrapper';
|
||||||
|
import type {
|
||||||
|
IConstraintsListProps as IEditableConstraintsListProps,
|
||||||
|
IConstraintsListRef as IEditableConstraintsListRef,
|
||||||
|
IConstraintsListItemState as IEditableConstraintsListItemState,
|
||||||
|
} from './ConstraintsListUtils';
|
||||||
|
import { useConstraintsList } from './ConstraintsListUtils';
|
||||||
|
|
||||||
|
export type { IEditableConstraintsListProps, IEditableConstraintsListRef };
|
||||||
|
|
||||||
|
export const editableConstraintsListId = 'editableConstraintsListId';
|
||||||
|
|
||||||
|
export const useEditableConstraintsList = useConstraintsList;
|
||||||
|
|
||||||
|
const StyledContainer = styled('div')({
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const EditableConstraintsList = forwardRef<
|
||||||
|
IEditableConstraintsListRef | undefined,
|
||||||
|
IEditableConstraintsListProps
|
||||||
|
>(({ constraints, setConstraints }, ref) => {
|
||||||
|
const { context } = useUnleashContext();
|
||||||
|
const state = useWeakMap<IConstraint, IEditableConstraintsListItemState>();
|
||||||
|
|
||||||
|
const onRemove =
|
||||||
|
setConstraints &&
|
||||||
|
((index: number) => {
|
||||||
|
const constraint = constraints[index];
|
||||||
|
state.set(constraint, {});
|
||||||
|
setConstraints(
|
||||||
|
produce((draft) => {
|
||||||
|
draft.splice(index, 1);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSave =
|
||||||
|
setConstraints &&
|
||||||
|
((index: number, constraint: IConstraint) => {
|
||||||
|
state.set(constraint, {});
|
||||||
|
setConstraints(
|
||||||
|
produce((draft) => {
|
||||||
|
draft[index] = constraint;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const onAutoSave =
|
||||||
|
setConstraints &&
|
||||||
|
((id: string | undefined) => (constraint: IConstraint) => {
|
||||||
|
state.set(constraint, { editing: true });
|
||||||
|
setConstraints(
|
||||||
|
produce((draft) => {
|
||||||
|
return draft.map((oldConstraint) => {
|
||||||
|
if (oldConstraint[constraintId] === id) {
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
return oldConstraint;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const onCancel = (index: number) => {
|
||||||
|
const constraint = constraints[index];
|
||||||
|
state.get(constraint)?.new && onRemove?.(index);
|
||||||
|
state.set(constraint, {});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (context.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledContainer id={editableConstraintsListId}>
|
||||||
|
<ConstraintsList>
|
||||||
|
{constraints.map((constraint, index) => (
|
||||||
|
<EditableConstraintWrapper
|
||||||
|
key={constraint[constraintId]}
|
||||||
|
constraint={constraint}
|
||||||
|
onCancel={onCancel?.bind(null, index)}
|
||||||
|
onDelete={onRemove?.bind(null, index)}
|
||||||
|
onSave={onSave!.bind(null, index)}
|
||||||
|
onAutoSave={onAutoSave?.(constraint[constraintId])}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ConstraintsList>
|
||||||
|
</StyledContainer>
|
||||||
|
);
|
||||||
|
});
|
@ -0,0 +1,72 @@
|
|||||||
|
import { forwardRef } from 'react';
|
||||||
|
import { styled } from '@mui/material';
|
||||||
|
import type { IConstraint } from 'interfaces/strategy';
|
||||||
|
import produce from 'immer';
|
||||||
|
import useUnleashContext from 'hooks/api/getters/useUnleashContext/useUnleashContext';
|
||||||
|
import { useWeakMap } from 'hooks/useWeakMap';
|
||||||
|
import { constraintId } from 'component/common/LegacyConstraintAccordion/ConstraintAccordionList/createEmptyConstraint';
|
||||||
|
import { ConstraintsList } from 'component/common/ConstraintsList/ConstraintsList';
|
||||||
|
import { ConstraintAccordionView } from 'component/common/NewConstraintAccordion/ConstraintAccordionView/ConstraintAccordionView';
|
||||||
|
import type {
|
||||||
|
IConstraintsListProps as IViewableConstraintsListProps,
|
||||||
|
IConstraintsListRef as IViewableConstraintsListRef,
|
||||||
|
IConstraintsListItemState as IViewableConstraintsListItemState,
|
||||||
|
} from './ConstraintsListUtils';
|
||||||
|
import { useConstraintsList } from './ConstraintsListUtils';
|
||||||
|
|
||||||
|
export type { IViewableConstraintsListProps, IViewableConstraintsListRef };
|
||||||
|
|
||||||
|
export const viewableConstraintsListId = 'viewableConstraintsListId';
|
||||||
|
|
||||||
|
export const useViewableConstraintsList = useConstraintsList;
|
||||||
|
|
||||||
|
const StyledContainer = styled('div')({
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ViewableConstraintsList = forwardRef<
|
||||||
|
IViewableConstraintsListRef | undefined,
|
||||||
|
IViewableConstraintsListProps
|
||||||
|
>(({ constraints, setConstraints }, ref) => {
|
||||||
|
const { context } = useUnleashContext();
|
||||||
|
const state = useWeakMap<IConstraint, IViewableConstraintsListItemState>();
|
||||||
|
|
||||||
|
const onEdit =
|
||||||
|
setConstraints &&
|
||||||
|
((constraint: IConstraint) => {
|
||||||
|
state.set(constraint, { editing: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
const onRemove =
|
||||||
|
setConstraints &&
|
||||||
|
((index: number) => {
|
||||||
|
const constraint = constraints[index];
|
||||||
|
state.set(constraint, {});
|
||||||
|
setConstraints(
|
||||||
|
produce((draft) => {
|
||||||
|
draft.splice(index, 1);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (context.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledContainer id={viewableConstraintsListId}>
|
||||||
|
<ConstraintsList>
|
||||||
|
{constraints.map((constraint, index) => (
|
||||||
|
<ConstraintAccordionView
|
||||||
|
key={constraint[constraintId]}
|
||||||
|
constraint={constraint}
|
||||||
|
onEdit={onEdit?.bind(null, constraint)}
|
||||||
|
onDelete={onRemove?.bind(null, index)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ConstraintsList>
|
||||||
|
</StyledContainer>
|
||||||
|
);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user