mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
visual changes representation (#2583)
This commit is contained in:
parent
e728ecba69
commit
c7fe4a5a01
@ -1,5 +1,5 @@
|
|||||||
import React, { FC, VFC } from 'react';
|
import React, { FC, VFC } from 'react';
|
||||||
import { Alert, Box, Popover, styled, Typography } from '@mui/material';
|
import { Alert, Box, styled } from '@mui/material';
|
||||||
import { ChangeRequestFeatureToggleChange } from '../ChangeRequestOverview/ChangeRequestFeatureToggleChange/ChangeRequestFeatureToggleChange';
|
import { ChangeRequestFeatureToggleChange } from '../ChangeRequestOverview/ChangeRequestFeatureToggleChange/ChangeRequestFeatureToggleChange';
|
||||||
import { objectId } from 'utils/objectId';
|
import { objectId } from 'utils/objectId';
|
||||||
import { ToggleStatusChange } from '../ChangeRequestOverview/ChangeRequestFeatureToggleChange/ToggleStatusChange';
|
import { ToggleStatusChange } from '../ChangeRequestOverview/ChangeRequestFeatureToggleChange/ToggleStatusChange';
|
||||||
@ -7,27 +7,24 @@ import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useCh
|
|||||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||||
import useToast from 'hooks/useToast';
|
import useToast from 'hooks/useToast';
|
||||||
import type {
|
import type {
|
||||||
|
IChange,
|
||||||
IChangeRequest,
|
IChangeRequest,
|
||||||
IChangeRequestDeleteStrategy,
|
IChangeRequestFeature,
|
||||||
IChangeRequestUpdateStrategy,
|
|
||||||
} from '../changeRequest.types';
|
} from '../changeRequest.types';
|
||||||
|
import { hasNameField } from '../changeRequest.types';
|
||||||
import {
|
import {
|
||||||
Discard,
|
Discard,
|
||||||
StrategyAddedChange,
|
StrategyAddedChange,
|
||||||
StrategyDeletedChange,
|
StrategyDeletedChange,
|
||||||
StrategyEditedChange,
|
StrategyEditedChange,
|
||||||
} from '../ChangeRequestOverview/ChangeRequestFeatureToggleChange/StrategyChange';
|
} from '../ChangeRequestOverview/ChangeRequestFeatureToggleChange/StrategyChange';
|
||||||
import {
|
|
||||||
formatStrategyName,
|
|
||||||
GetFeatureStrategyIcon,
|
|
||||||
} from 'utils/strategyNames';
|
|
||||||
import {
|
|
||||||
hasNameField,
|
|
||||||
IChangeRequestAddStrategy,
|
|
||||||
} from '../changeRequest.types';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
|
||||||
import EventDiff from '../../events/EventDiff/EventDiff';
|
import { StrategyExecution } from '../../feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyExecution/StrategyExecution';
|
||||||
|
import {
|
||||||
|
CodeSnippetPopover,
|
||||||
|
PopoverDiff,
|
||||||
|
} from './CodeSnippetPopover/CodeSnippetPopover';
|
||||||
|
|
||||||
interface IChangeRequestProps {
|
interface IChangeRequestProps {
|
||||||
changeRequest: IChangeRequest;
|
changeRequest: IChangeRequest;
|
||||||
@ -77,61 +74,121 @@ const StyledAlert = styled(Alert)(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const CodeSnippetPopover: FC<{
|
const Change: FC<{
|
||||||
change:
|
onDiscard: () => Promise<void>;
|
||||||
| IChangeRequestAddStrategy
|
index: number;
|
||||||
| IChangeRequestUpdateStrategy
|
changeRequest: IChangeRequest;
|
||||||
| IChangeRequestDeleteStrategy;
|
change: IChange;
|
||||||
}> = ({ change }) => {
|
feature: IChangeRequestFeature;
|
||||||
const [anchorEl, setAnchorEl] = React.useState<HTMLElement | null>(null);
|
}> = ({ index, change, feature, changeRequest, onDiscard }) => {
|
||||||
|
const { isChangeRequestConfigured } = useChangeRequestsEnabled(
|
||||||
|
changeRequest.project
|
||||||
|
);
|
||||||
|
const allowChangeRequestActions = isChangeRequestConfigured(
|
||||||
|
changeRequest.environment
|
||||||
|
);
|
||||||
|
|
||||||
const handlePopoverOpen = (event: React.MouseEvent<HTMLElement>) => {
|
const showDiscard =
|
||||||
setAnchorEl(event.currentTarget);
|
allowChangeRequestActions &&
|
||||||
};
|
!['Cancelled', 'Applied'].includes(changeRequest.state) &&
|
||||||
|
changeRequest.features.flatMap(feature => feature.changes).length > 1;
|
||||||
const handlePopoverClose = () => {
|
|
||||||
setAnchorEl(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
const open = Boolean(anchorEl);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<StyledSingleChangeBox
|
||||||
<GetFeatureStrategyIcon strategyName={change.payload.name} />
|
key={objectId(change)}
|
||||||
|
$hasConflict={Boolean(change.conflict)}
|
||||||
<Typography
|
$isInConflictFeature={Boolean(feature.conflict)}
|
||||||
onMouseEnter={handlePopoverOpen}
|
$isAfterWarning={Boolean(feature.changes[index - 1]?.conflict)}
|
||||||
onMouseLeave={handlePopoverClose}
|
$isLast={index + 1 === feature.changes.length}
|
||||||
>
|
>
|
||||||
{formatStrategyName(change.payload.name)}
|
<ConditionallyRender
|
||||||
</Typography>
|
condition={Boolean(change.conflict) && !feature.conflict}
|
||||||
<Popover
|
show={
|
||||||
id={String(change.id)}
|
<StyledAlert severity="warning">
|
||||||
sx={{
|
<strong>Conflict!</strong> This change can’t be applied.{' '}
|
||||||
pointerEvents: 'none',
|
{change.conflict}.
|
||||||
}}
|
</StyledAlert>
|
||||||
open={open}
|
}
|
||||||
anchorEl={anchorEl}
|
|
||||||
anchorOrigin={{
|
|
||||||
vertical: 'bottom',
|
|
||||||
horizontal: 'left',
|
|
||||||
}}
|
|
||||||
transformOrigin={{
|
|
||||||
vertical: 'top',
|
|
||||||
horizontal: 'left',
|
|
||||||
}}
|
|
||||||
onClose={handlePopoverClose}
|
|
||||||
disableRestoreFocus
|
|
||||||
>
|
|
||||||
<Box sx={{ paddingLeft: 3, paddingRight: 3 }}>
|
|
||||||
<EventDiff
|
|
||||||
entry={{
|
|
||||||
data: change.payload,
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
<Box sx={{ p: 2 }}>
|
||||||
</Popover>
|
{change.action === 'updateEnabled' && (
|
||||||
|
<ToggleStatusChange
|
||||||
|
enabled={change.payload.enabled}
|
||||||
|
discard={
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showDiscard}
|
||||||
|
show={<Discard onDiscard={onDiscard} />}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{change.action === 'addStrategy' && (
|
||||||
|
<>
|
||||||
|
<StrategyAddedChange
|
||||||
|
discard={
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showDiscard}
|
||||||
|
show={<Discard onDiscard={onDiscard} />}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<CodeSnippetPopover change={change}>
|
||||||
|
<PopoverDiff
|
||||||
|
change={change}
|
||||||
|
feature={feature.name}
|
||||||
|
environmentName={changeRequest.environment}
|
||||||
|
project={changeRequest.project}
|
||||||
|
/>
|
||||||
|
</CodeSnippetPopover>
|
||||||
|
</StrategyAddedChange>
|
||||||
|
<StrategyExecution strategy={change.payload} />
|
||||||
</>
|
</>
|
||||||
|
)}
|
||||||
|
{change.action === 'deleteStrategy' && (
|
||||||
|
<StrategyDeletedChange
|
||||||
|
discard={
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showDiscard}
|
||||||
|
show={<Discard onDiscard={onDiscard} />}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{hasNameField(change.payload) && (
|
||||||
|
<CodeSnippetPopover change={change}>
|
||||||
|
<PopoverDiff
|
||||||
|
change={change}
|
||||||
|
feature={feature.name}
|
||||||
|
environmentName={changeRequest.environment}
|
||||||
|
project={changeRequest.project}
|
||||||
|
/>
|
||||||
|
</CodeSnippetPopover>
|
||||||
|
)}
|
||||||
|
</StrategyDeletedChange>
|
||||||
|
)}
|
||||||
|
{change.action === 'updateStrategy' && (
|
||||||
|
<>
|
||||||
|
<StrategyEditedChange
|
||||||
|
discard={
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showDiscard}
|
||||||
|
show={<Discard onDiscard={onDiscard} />}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<CodeSnippetPopover change={change}>
|
||||||
|
<PopoverDiff
|
||||||
|
change={change}
|
||||||
|
feature={feature.name}
|
||||||
|
environmentName={changeRequest.environment}
|
||||||
|
project={changeRequest.project}
|
||||||
|
/>
|
||||||
|
</CodeSnippetPopover>
|
||||||
|
</StrategyEditedChange>
|
||||||
|
<StrategyExecution strategy={change.payload} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</StyledSingleChangeBox>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -154,132 +211,25 @@ export const ChangeRequest: VFC<IChangeRequestProps> = ({
|
|||||||
setToastApiError(formatUnknownError(error));
|
setToastApiError(formatUnknownError(error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const { isChangeRequestConfigured } = useChangeRequestsEnabled(
|
|
||||||
changeRequest.project
|
|
||||||
);
|
|
||||||
const allowChangeRequestActions = isChangeRequestConfigured(
|
|
||||||
changeRequest.environment
|
|
||||||
);
|
|
||||||
|
|
||||||
const showDiscard =
|
|
||||||
allowChangeRequestActions &&
|
|
||||||
!['Cancelled', 'Applied'].includes(changeRequest.state) &&
|
|
||||||
changeRequest.features.flatMap(feature => feature.changes).length > 1;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
{changeRequest.features?.map(featureToggleChange => (
|
{changeRequest.features?.map(feature => (
|
||||||
<ChangeRequestFeatureToggleChange
|
<ChangeRequestFeatureToggleChange
|
||||||
key={featureToggleChange.name}
|
key={feature.name}
|
||||||
featureName={featureToggleChange.name}
|
featureName={feature.name}
|
||||||
projectId={changeRequest.project}
|
projectId={changeRequest.project}
|
||||||
onNavigate={onNavigate}
|
onNavigate={onNavigate}
|
||||||
conflict={featureToggleChange.conflict}
|
conflict={feature.conflict}
|
||||||
>
|
>
|
||||||
{featureToggleChange.changes.map((change, index) => (
|
{feature.changes.map((change, index) => (
|
||||||
<StyledSingleChangeBox
|
<Change
|
||||||
key={objectId(change)}
|
onDiscard={onDiscard(change.id)}
|
||||||
$hasConflict={Boolean(change.conflict)}
|
index={index}
|
||||||
$isInConflictFeature={Boolean(
|
changeRequest={changeRequest}
|
||||||
featureToggleChange.conflict
|
|
||||||
)}
|
|
||||||
$isAfterWarning={Boolean(
|
|
||||||
featureToggleChange.changes[index - 1]?.conflict
|
|
||||||
)}
|
|
||||||
$isLast={
|
|
||||||
index + 1 === featureToggleChange.changes.length
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={
|
|
||||||
Boolean(change.conflict) &&
|
|
||||||
!featureToggleChange.conflict
|
|
||||||
}
|
|
||||||
show={
|
|
||||||
<StyledAlert severity="warning">
|
|
||||||
<strong>Conflict!</strong> This change
|
|
||||||
can’t be applied. {change.conflict}.
|
|
||||||
</StyledAlert>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Box sx={{ p: 2 }}>
|
|
||||||
{change.action === 'updateEnabled' && (
|
|
||||||
<ToggleStatusChange
|
|
||||||
enabled={change.payload.enabled}
|
|
||||||
discard={
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={showDiscard}
|
|
||||||
show={
|
|
||||||
<Discard
|
|
||||||
onDiscard={onDiscard(
|
|
||||||
change.id
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{change.action === 'addStrategy' && (
|
|
||||||
<StrategyAddedChange
|
|
||||||
discard={
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={showDiscard}
|
|
||||||
show={
|
|
||||||
<Discard
|
|
||||||
onDiscard={onDiscard(
|
|
||||||
change.id
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<CodeSnippetPopover change={change} />
|
|
||||||
</StrategyAddedChange>
|
|
||||||
)}
|
|
||||||
{change.action === 'deleteStrategy' && (
|
|
||||||
<StrategyDeletedChange
|
|
||||||
discard={
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={showDiscard}
|
|
||||||
show={
|
|
||||||
<Discard
|
|
||||||
onDiscard={onDiscard(
|
|
||||||
change.id
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{hasNameField(change.payload) && (
|
|
||||||
<CodeSnippetPopover
|
|
||||||
change={change}
|
change={change}
|
||||||
|
feature={feature}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</StrategyDeletedChange>
|
|
||||||
)}
|
|
||||||
{change.action === 'updateStrategy' && (
|
|
||||||
<StrategyEditedChange
|
|
||||||
discard={
|
|
||||||
<ConditionallyRender
|
|
||||||
condition={showDiscard}
|
|
||||||
show={
|
|
||||||
<Discard
|
|
||||||
onDiscard={onDiscard(
|
|
||||||
change.id
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<CodeSnippetPopover change={change} />
|
|
||||||
</StrategyEditedChange>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</StyledSingleChangeBox>
|
|
||||||
))}
|
))}
|
||||||
</ChangeRequestFeatureToggleChange>
|
</ChangeRequestFeatureToggleChange>
|
||||||
))}
|
))}
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
import {
|
||||||
|
IChangeRequestAddStrategy,
|
||||||
|
IChangeRequestDeleteStrategy,
|
||||||
|
IChangeRequestUpdateStrategy,
|
||||||
|
} from '../../changeRequest.types';
|
||||||
|
import React, { FC } from 'react';
|
||||||
|
import {
|
||||||
|
formatStrategyName,
|
||||||
|
GetFeatureStrategyIcon,
|
||||||
|
} from '../../../../utils/strategyNames';
|
||||||
|
import { Popover, Typography } from '@mui/material';
|
||||||
|
import { useFeature } from '../../../../hooks/api/getters/useFeature/useFeature';
|
||||||
|
import { StyledCodeSection } from '../../../events/EventCard/EventCard';
|
||||||
|
import EventDiff from '../../../events/EventDiff/EventDiff';
|
||||||
|
|
||||||
|
const useCurrentStrategy = (
|
||||||
|
change:
|
||||||
|
| IChangeRequestAddStrategy
|
||||||
|
| IChangeRequestUpdateStrategy
|
||||||
|
| IChangeRequestDeleteStrategy,
|
||||||
|
project: string,
|
||||||
|
feature: string,
|
||||||
|
environmentName: string
|
||||||
|
) => {
|
||||||
|
const currentFeature = useFeature(project, feature);
|
||||||
|
const currentStrategy = currentFeature.feature?.environments
|
||||||
|
.find(environment => environment.name === environmentName)
|
||||||
|
?.strategies.find(
|
||||||
|
strategy =>
|
||||||
|
'id' in change.payload && strategy.id === change.payload.id
|
||||||
|
);
|
||||||
|
return currentStrategy;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PopoverDiff: FC<{
|
||||||
|
change:
|
||||||
|
| IChangeRequestAddStrategy
|
||||||
|
| IChangeRequestUpdateStrategy
|
||||||
|
| IChangeRequestDeleteStrategy;
|
||||||
|
project: string;
|
||||||
|
feature: string;
|
||||||
|
environmentName: string;
|
||||||
|
}> = ({ change, project, feature, environmentName }) => {
|
||||||
|
const currentStrategy = useCurrentStrategy(
|
||||||
|
change,
|
||||||
|
project,
|
||||||
|
feature,
|
||||||
|
environmentName
|
||||||
|
);
|
||||||
|
const changeRequestStrategy =
|
||||||
|
change.action === 'deleteStrategy' ? undefined : change.payload;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledCodeSection>
|
||||||
|
<EventDiff
|
||||||
|
entry={{
|
||||||
|
preData: currentStrategy,
|
||||||
|
data: changeRequestStrategy,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</StyledCodeSection>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
interface ICodeSnippetPopoverProps {
|
||||||
|
change:
|
||||||
|
| IChangeRequestAddStrategy
|
||||||
|
| IChangeRequestUpdateStrategy
|
||||||
|
| IChangeRequestDeleteStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// based on: https://mui.com/material-ui/react-popover/#mouse-over-interaction
|
||||||
|
export const CodeSnippetPopover: FC<ICodeSnippetPopoverProps> = ({
|
||||||
|
change,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const [anchorEl, setAnchorEl] = React.useState<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
const handlePopoverOpen = (event: React.MouseEvent<HTMLElement>) => {
|
||||||
|
setAnchorEl(event.currentTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePopoverClose = () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const open = Boolean(anchorEl);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<GetFeatureStrategyIcon strategyName={change.payload.name} />
|
||||||
|
|
||||||
|
<Typography
|
||||||
|
onMouseEnter={handlePopoverOpen}
|
||||||
|
onMouseLeave={handlePopoverClose}
|
||||||
|
>
|
||||||
|
{formatStrategyName(change.payload.name)}
|
||||||
|
</Typography>
|
||||||
|
<Popover
|
||||||
|
id={String(change.id)}
|
||||||
|
sx={{
|
||||||
|
pointerEvents: 'none',
|
||||||
|
}}
|
||||||
|
open={open}
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: 'bottom',
|
||||||
|
horizontal: 'left',
|
||||||
|
}}
|
||||||
|
transformOrigin={{
|
||||||
|
vertical: 'top',
|
||||||
|
horizontal: 'left',
|
||||||
|
}}
|
||||||
|
onClose={handlePopoverClose}
|
||||||
|
disableRestoreFocus
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -40,7 +40,7 @@ const StyledContainerListItem = styled('li')(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledCodeSection = styled('div')(({ theme }) => ({
|
export const StyledCodeSection = styled('div')(({ theme }) => ({
|
||||||
backgroundColor: 'white',
|
backgroundColor: 'white',
|
||||||
overflowX: 'auto',
|
overflowX: 'auto',
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Fragment, useMemo, VFC } from 'react';
|
import { Fragment, useMemo, VFC } from 'react';
|
||||||
import { Box, Chip } from '@mui/material';
|
import { Box, Chip } from '@mui/material';
|
||||||
import { IFeatureStrategy } from 'interfaces/strategy';
|
import { IFeatureStrategy, IFeatureStrategyPayload } from 'interfaces/strategy';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle';
|
import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle';
|
||||||
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
||||||
@ -19,7 +19,7 @@ import {
|
|||||||
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
||||||
|
|
||||||
interface IStrategyExecutionProps {
|
interface IStrategyExecutionProps {
|
||||||
strategy: IFeatureStrategy;
|
strategy: IFeatureStrategyPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NoItems: VFC = () => (
|
const NoItems: VFC = () => (
|
||||||
@ -35,7 +35,10 @@ export const StrategyExecution: VFC<IStrategyExecutionProps> = ({
|
|||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
const { strategies } = useStrategies();
|
const { strategies } = useStrategies();
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
const { segments } = useSegments(strategy.id);
|
const { segments } = useSegments();
|
||||||
|
const strategySegments = segments?.filter(segment => {
|
||||||
|
return strategy.segments?.includes(segment.id);
|
||||||
|
});
|
||||||
|
|
||||||
const definition = strategies.find(strategyDefinition => {
|
const definition = strategies.find(strategyDefinition => {
|
||||||
return strategyDefinition.name === strategy.name;
|
return strategyDefinition.name === strategy.name;
|
||||||
@ -243,8 +246,10 @@ export const StrategyExecution: VFC<IStrategyExecutionProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const listItems = [
|
const listItems = [
|
||||||
Boolean(uiConfig.flags.SE) && segments && segments.length > 0 && (
|
Boolean(uiConfig.flags.SE) &&
|
||||||
<FeatureOverviewSegment strategyId={strategy.id} />
|
strategySegments &&
|
||||||
|
strategySegments.length > 0 && (
|
||||||
|
<FeatureOverviewSegment segments={strategySegments} />
|
||||||
),
|
),
|
||||||
constraints.length > 0 && (
|
constraints.length > 0 && (
|
||||||
<ConstraintAccordionList
|
<ConstraintAccordionList
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
import { useSegments } from 'hooks/api/getters/useSegments/useSegments';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
import { StrategySeparator } from 'component/common/StrategySeparator/StrategySeparator';
|
||||||
import { SegmentItem } from '../../../../common/SegmentItem/SegmentItem';
|
import { SegmentItem } from '../../../../common/SegmentItem/SegmentItem';
|
||||||
|
import { ISegment } from 'interfaces/segment';
|
||||||
|
|
||||||
interface IFeatureOverviewSegmentProps {
|
interface IFeatureOverviewSegmentProps {
|
||||||
strategyId: string;
|
segments?: ISegment[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FeatureOverviewSegment = ({
|
export const FeatureOverviewSegment = ({
|
||||||
strategyId,
|
segments,
|
||||||
}: IFeatureOverviewSegmentProps) => {
|
}: IFeatureOverviewSegmentProps) => {
|
||||||
const { segments } = useSegments(strategyId);
|
|
||||||
|
|
||||||
if (!segments || segments.length === 0) {
|
if (!segments || segments.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user