mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-24 01:18:01 +02:00
Playground result info modal initial
This commit is contained in:
parent
562ca62b42
commit
e894cbb52a
@ -3,19 +3,11 @@ import React, { ReactNode } from 'react';
|
|||||||
|
|
||||||
interface IIconCellProps {
|
interface IIconCellProps {
|
||||||
icon: ReactNode;
|
icon: ReactNode;
|
||||||
onClick?: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IconCell = ({ icon, onClick }: IIconCellProps) => {
|
export const IconCell = ({ icon }: IIconCellProps) => {
|
||||||
const handleClick =
|
|
||||||
onClick &&
|
|
||||||
((event: React.SyntheticEvent) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
onClick();
|
|
||||||
});
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
onClick={handleClick}
|
|
||||||
sx={{
|
sx={{
|
||||||
pl: 2,
|
pl: 2,
|
||||||
pr: 1,
|
pr: 1,
|
||||||
|
@ -24,6 +24,9 @@ export const useStyles = makeStyles()(theme => ({
|
|||||||
marginLeft: 'auto',
|
marginLeft: 'auto',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
},
|
},
|
||||||
|
resultChip: {
|
||||||
|
marginLeft: 'auto',
|
||||||
|
},
|
||||||
body: {
|
body: {
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
justifyItems: 'center',
|
justifyItems: 'center',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { DragIndicator, Edit } from '@mui/icons-material';
|
import { DragIndicator, Edit } from '@mui/icons-material';
|
||||||
import { styled, useTheme, IconButton } from '@mui/material';
|
import { styled, useTheme, IconButton, Chip } from '@mui/material';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { IFeatureStrategy } from 'interfaces/strategy';
|
import {IFeatureStrategy, IPlaygroundFeatureStrategyResult} from 'interfaces/strategy';
|
||||||
import {
|
import {
|
||||||
getFeatureStrategyIcon,
|
getFeatureStrategyIcon,
|
||||||
formatStrategyName,
|
formatStrategyName,
|
||||||
@ -18,8 +18,10 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
|
|||||||
|
|
||||||
interface IStrategyItemProps {
|
interface IStrategyItemProps {
|
||||||
environmentId: string;
|
environmentId: string;
|
||||||
strategy: IFeatureStrategy;
|
strategy: IFeatureStrategy | IPlaygroundFeatureStrategyResult;
|
||||||
isDraggable?: boolean;
|
isDraggable?: boolean;
|
||||||
|
showActions?: boolean;
|
||||||
|
result?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DragIcon = styled(IconButton)(({ theme }) => ({
|
const DragIcon = styled(IconButton)(({ theme }) => ({
|
||||||
@ -32,6 +34,8 @@ export const StrategyItem = ({
|
|||||||
environmentId,
|
environmentId,
|
||||||
strategy,
|
strategy,
|
||||||
isDraggable,
|
isDraggable,
|
||||||
|
showActions = true,
|
||||||
|
result,
|
||||||
}: IStrategyItemProps) => {
|
}: IStrategyItemProps) => {
|
||||||
const projectId = useRequiredPathParam('projectId');
|
const projectId = useRequiredPathParam('projectId');
|
||||||
const featureId = useRequiredPathParam('featureId');
|
const featureId = useRequiredPathParam('featureId');
|
||||||
@ -46,6 +50,8 @@ export const StrategyItem = ({
|
|||||||
strategy.id
|
strategy.id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const showShouldShowResultChip = result !== undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
@ -66,6 +72,9 @@ export const StrategyItem = ({
|
|||||||
maxLength={15}
|
maxLength={15}
|
||||||
text={formatStrategyName(strategy.name)}
|
text={formatStrategyName(strategy.name)}
|
||||||
/>
|
/>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showActions}
|
||||||
|
show={
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
<PermissionIconButton
|
<PermissionIconButton
|
||||||
permission={UPDATE_FEATURE_STRATEGY}
|
permission={UPDATE_FEATURE_STRATEGY}
|
||||||
@ -85,6 +94,14 @@ export const StrategyItem = ({
|
|||||||
icon
|
icon
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showShouldShowResultChip}
|
||||||
|
show={
|
||||||
|
<Featur>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.body}>
|
<div className={styles.body}>
|
||||||
<StrategyExecution
|
<StrategyExecution
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import { PlaygroundFeatureSchema } from '../../../../hooks/api/actions/usePlayground/playground.model';
|
|
||||||
import { Modal } from '@mui/material';
|
|
||||||
|
|
||||||
interface PlaygroundFeatureResultInfoModalProps {
|
|
||||||
feature?: PlaygroundFeatureSchema;
|
|
||||||
open: boolean;
|
|
||||||
setOpen: (open: boolean) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PlaygroundFeatureResultInfoModal = ({
|
|
||||||
feature,
|
|
||||||
open,
|
|
||||||
setOpen,
|
|
||||||
}: PlaygroundFeatureResultInfoModalProps) => {
|
|
||||||
if (!feature) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal open={open} onClose={() => setOpen(false)}>
|
|
||||||
<p>Test</p>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
@ -0,0 +1,85 @@
|
|||||||
|
import { PlaygroundFeatureSchema } from '../../../../../hooks/api/actions/usePlayground/playground.model';
|
||||||
|
import { Box, IconButton, Popover } from '@mui/material';
|
||||||
|
import { InfoOutlined } from '@mui/icons-material';
|
||||||
|
import { IconCell } from '../../../../common/Table/cells/IconCell/IconCell';
|
||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
interface FeatureResultInfoPopoverCellProps {
|
||||||
|
feature?: PlaygroundFeatureSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FeatureResultInfoPopoverCell = ({
|
||||||
|
feature,
|
||||||
|
}: FeatureResultInfoPopoverCellProps) => {
|
||||||
|
if (!feature) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const ref = useRef(null);
|
||||||
|
|
||||||
|
const togglePopover = (event: React.SyntheticEvent) => {
|
||||||
|
setOpen(!open);
|
||||||
|
};
|
||||||
|
|
||||||
|
const strategies = [
|
||||||
|
{
|
||||||
|
type: 'standard',
|
||||||
|
id: 'strategy-id',
|
||||||
|
result: false,
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
result: false,
|
||||||
|
contextName: 'appName',
|
||||||
|
operator: 'IN',
|
||||||
|
caseInsensitive: true,
|
||||||
|
inverted: false,
|
||||||
|
values: ['a', 'b'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
segments: [
|
||||||
|
{
|
||||||
|
result: true,
|
||||||
|
id: 5,
|
||||||
|
name: 'my-segment',
|
||||||
|
constraints: [
|
||||||
|
{
|
||||||
|
result: false,
|
||||||
|
contextName: 'appName',
|
||||||
|
operator: 'IN',
|
||||||
|
caseInsensitive: true,
|
||||||
|
inverted: false,
|
||||||
|
values: ['a', 'b'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'default',
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<IconButton onClick={togglePopover}>
|
||||||
|
<InfoOutlined ref={ref} />
|
||||||
|
</IconButton>
|
||||||
|
<Popover
|
||||||
|
open={open}
|
||||||
|
onClose={() => setOpen(false)}
|
||||||
|
anchorEl={ref.current}
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: 'top',
|
||||||
|
horizontal: 'right',
|
||||||
|
}}
|
||||||
|
transformOrigin={{
|
||||||
|
vertical: 'center',
|
||||||
|
horizontal: 'left',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{feature.name}
|
||||||
|
</Popover>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,38 @@
|
|||||||
|
import { ConditionallyRender } from '../../../../../common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { StrategySeparator } from '../../../../../common/StrategySeparator/StrategySeparator';
|
||||||
|
import { StrategyItem } from '../../../../../feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem';
|
||||||
|
import {
|
||||||
|
IConstraint,
|
||||||
|
IFeatureStrategy, IPlaygroundFeatureStrategyResult,
|
||||||
|
} from '../../../../../../interfaces/strategy';
|
||||||
|
import { ISegment } from '../../../../../../interfaces/segment';
|
||||||
|
|
||||||
|
|
||||||
|
interface IPlaygroundResultFeatureStrategyItemProps {
|
||||||
|
strategy: IPlaygroundFeatureStrategyResult;
|
||||||
|
environmentName: string;
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PlaygroundResultFeatureStrategyItem = ({
|
||||||
|
strategy,
|
||||||
|
environmentName,
|
||||||
|
index,
|
||||||
|
}: IPlaygroundResultFeatureStrategyItemProps) => {
|
||||||
|
const { result } = strategy;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={strategy.id} className={``}>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={index > 0}
|
||||||
|
show={<StrategySeparator text="OR" />}
|
||||||
|
/>
|
||||||
|
<StrategyItem
|
||||||
|
strategy={strategy}
|
||||||
|
result={result}
|
||||||
|
environmentId={environmentName}
|
||||||
|
isDraggable={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -4,37 +4,12 @@ import { ReactComponent as FeatureEnabledIcon } from 'assets/icons/isenabled-tru
|
|||||||
import { ReactComponent as FeatureDisabledIcon } from 'assets/icons/isenabled-false.svg';
|
import { ReactComponent as FeatureDisabledIcon } from 'assets/icons/isenabled-false.svg';
|
||||||
import { Box, Chip, styled, useTheme } from '@mui/material';
|
import { Box, Chip, styled, useTheme } from '@mui/material';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import {ResultChip} from "../ResultChip/ResultChip";
|
||||||
|
|
||||||
interface IFeatureStatusCellProps {
|
interface IFeatureStatusCellProps {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledFalseChip = styled(Chip)(({ theme }) => ({
|
|
||||||
width: 80,
|
|
||||||
borderRadius: '5px',
|
|
||||||
border: `1px solid ${theme.palette.error.main}`,
|
|
||||||
backgroundColor: colors.red['200'],
|
|
||||||
['& .MuiChip-label']: {
|
|
||||||
color: theme.palette.error.main,
|
|
||||||
},
|
|
||||||
['& .MuiChip-icon']: {
|
|
||||||
color: theme.palette.error.main,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledTrueChip = styled(Chip)(({ theme }) => ({
|
|
||||||
width: 80,
|
|
||||||
borderRadius: '5px',
|
|
||||||
border: `1px solid ${theme.palette.success.main}`,
|
|
||||||
backgroundColor: colors.green['100'],
|
|
||||||
['& .MuiChip-label']: {
|
|
||||||
color: theme.palette.success.main,
|
|
||||||
},
|
|
||||||
['& .MuiChip-icon']: {
|
|
||||||
color: theme.palette.success.main,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const StyledCellBox = styled(Box)(({ theme }) => ({
|
const StyledCellBox = styled(Box)(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
@ -70,11 +45,7 @@ export const FeatureStatusCell = ({ enabled }: IFeatureStatusCellProps) => {
|
|||||||
return (
|
return (
|
||||||
<StyledCellBox>
|
<StyledCellBox>
|
||||||
<StyledChipWrapper data-loading>
|
<StyledChipWrapper data-loading>
|
||||||
<ConditionallyRender
|
<ResultChip enabled label={label} icon={icon} />
|
||||||
condition={enabled}
|
|
||||||
show={<StyledTrueChip icon={icon} label={label} />}
|
|
||||||
elseShow={<StyledFalseChip icon={icon} label={label} />}
|
|
||||||
/>
|
|
||||||
</StyledChipWrapper>
|
</StyledChipWrapper>
|
||||||
</StyledCellBox>
|
</StyledCellBox>
|
||||||
);
|
);
|
||||||
|
@ -25,7 +25,7 @@ import useLoading from 'hooks/useLoading';
|
|||||||
import { VariantCell } from './VariantCell/VariantCell';
|
import { VariantCell } from './VariantCell/VariantCell';
|
||||||
import { IconCell } from '../../../common/Table/cells/IconCell/IconCell';
|
import { IconCell } from '../../../common/Table/cells/IconCell/IconCell';
|
||||||
import { InfoOutlined } from '@mui/icons-material';
|
import { InfoOutlined } from '@mui/icons-material';
|
||||||
import { PlaygroundFeatureResultInfoModal } from '../PlaygroundFeatureResultInfoModal/PlaygroundFeatureResultInfoModal';
|
import { FeatureResultInfoPopoverCell } from './FeatureResultInfoPopoverCell/FeatureResultInfoPopoverCell';
|
||||||
|
|
||||||
const defaultSort: SortingRule<string> = { id: 'name' };
|
const defaultSort: SortingRule<string> = { id: 'name' };
|
||||||
const { value, setValue } = createLocalStorage(
|
const { value, setValue } = createLocalStorage(
|
||||||
@ -51,87 +51,11 @@ export const PlaygroundResultsTable = ({
|
|||||||
const isExtraSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
const isExtraSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
|
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
|
|
||||||
const [selectedFeature, setSelectedFeature] = useState<
|
|
||||||
PlaygroundFeatureSchema | undefined
|
|
||||||
>();
|
|
||||||
const [showResultInfoModal, setShowResultInfoModal] = useState(false);
|
|
||||||
|
|
||||||
const columns = useMemo(
|
|
||||||
() => [
|
|
||||||
{
|
|
||||||
Header: 'Name',
|
|
||||||
accessor: 'name',
|
|
||||||
searchable: true,
|
|
||||||
minWidth: 160,
|
|
||||||
Cell: ({ value, row: { original } }: any) => (
|
|
||||||
<LinkCell
|
|
||||||
title={value}
|
|
||||||
to={`/projects/${original?.projectId}/features/${value}`}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Header: 'Project ID',
|
|
||||||
accessor: 'projectId',
|
|
||||||
sortType: 'alphanumeric',
|
|
||||||
filterName: 'projectId',
|
|
||||||
searchable: true,
|
|
||||||
maxWidth: 170,
|
|
||||||
Cell: ({ value }: any) => (
|
|
||||||
<LinkCell title={value} to={`/projects/${value}`} />
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Header: 'Variant',
|
|
||||||
id: 'variant',
|
|
||||||
accessor: 'variant.name',
|
|
||||||
sortType: 'alphanumeric',
|
|
||||||
filterName: 'variant',
|
|
||||||
searchable: true,
|
|
||||||
width: 200,
|
|
||||||
Cell: ({
|
|
||||||
value,
|
|
||||||
row: {
|
|
||||||
original: { variant, feature, variants, isEnabled },
|
|
||||||
},
|
|
||||||
}: any) => (
|
|
||||||
<VariantCell
|
|
||||||
variant={variant?.enabled ? value : ''}
|
|
||||||
variants={variants}
|
|
||||||
feature={feature}
|
|
||||||
isEnabled={isEnabled}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Header: 'isEnabled',
|
|
||||||
accessor: 'isEnabled',
|
|
||||||
filterName: 'isEnabled',
|
|
||||||
filterParsing: (value: boolean) => (value ? 'true' : 'false'),
|
|
||||||
Cell: ({ value }: any) => <FeatureStatusCell enabled={value} />,
|
|
||||||
sortType: 'boolean',
|
|
||||||
sortInverted: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Header: '',
|
|
||||||
id: 'info',
|
|
||||||
Cell: ({ row }: any) => (
|
|
||||||
<IconCell
|
|
||||||
icon={<InfoOutlined />}
|
|
||||||
onClick={() => onFeatureResultInfoClick(row.original)}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
//eslint-disable-next-line
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: searchedData,
|
data: searchedData,
|
||||||
getSearchText,
|
getSearchText,
|
||||||
getSearchContext,
|
getSearchContext,
|
||||||
} = useSearch(columns, searchValue, features || []);
|
} = useSearch(COLUMNS, searchValue, features || []);
|
||||||
|
|
||||||
const data = useMemo(() => {
|
const data = useMemo(() => {
|
||||||
return loading
|
return loading
|
||||||
@ -166,7 +90,7 @@ export const PlaygroundResultsTable = ({
|
|||||||
} = useTable(
|
} = useTable(
|
||||||
{
|
{
|
||||||
initialState,
|
initialState,
|
||||||
columns: columns as any,
|
columns: COLUMNS as any,
|
||||||
data: data as any,
|
data: data as any,
|
||||||
sortTypes,
|
sortTypes,
|
||||||
autoResetGlobalFilter: false,
|
autoResetGlobalFilter: false,
|
||||||
@ -217,18 +141,8 @@ export const PlaygroundResultsTable = ({
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps -- don't re-render after search params change
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- don't re-render after search params change
|
||||||
}, [loading, sortBy, searchValue]);
|
}, [loading, sortBy, searchValue]);
|
||||||
|
|
||||||
const onFeatureResultInfoClick = (feature: PlaygroundFeatureSchema) => {
|
|
||||||
setSelectedFeature(feature);
|
|
||||||
setShowResultInfoModal(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PlaygroundFeatureResultInfoModal
|
|
||||||
feature={selectedFeature}
|
|
||||||
open={showResultInfoModal}
|
|
||||||
setOpen={setShowResultInfoModal}
|
|
||||||
/>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -324,3 +238,67 @@ export const PlaygroundResultsTable = ({
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const COLUMNS = [
|
||||||
|
{
|
||||||
|
Header: 'Name',
|
||||||
|
accessor: 'name',
|
||||||
|
searchable: true,
|
||||||
|
minWidth: 160,
|
||||||
|
Cell: ({ value, row: { original } }: any) => (
|
||||||
|
<LinkCell
|
||||||
|
title={value}
|
||||||
|
to={`/projects/${original?.projectId}/features/${value}`}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Project ID',
|
||||||
|
accessor: 'projectId',
|
||||||
|
sortType: 'alphanumeric',
|
||||||
|
filterName: 'projectId',
|
||||||
|
searchable: true,
|
||||||
|
maxWidth: 170,
|
||||||
|
Cell: ({ value }: any) => (
|
||||||
|
<LinkCell title={value} to={`/projects/${value}`} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Variant',
|
||||||
|
id: 'variant',
|
||||||
|
accessor: 'variant.name',
|
||||||
|
sortType: 'alphanumeric',
|
||||||
|
filterName: 'variant',
|
||||||
|
searchable: true,
|
||||||
|
width: 200,
|
||||||
|
Cell: ({
|
||||||
|
value,
|
||||||
|
row: {
|
||||||
|
original: { variant, feature, variants, isEnabled },
|
||||||
|
},
|
||||||
|
}: any) => (
|
||||||
|
<VariantCell
|
||||||
|
variant={variant?.enabled ? value : ''}
|
||||||
|
variants={variants}
|
||||||
|
feature={feature}
|
||||||
|
isEnabled={isEnabled}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'isEnabled',
|
||||||
|
accessor: 'isEnabled',
|
||||||
|
filterName: 'isEnabled',
|
||||||
|
filterParsing: (value: boolean) => (value ? 'true' : 'false'),
|
||||||
|
Cell: ({ value }: any) => <FeatureStatusCell enabled={value} />,
|
||||||
|
sortType: 'boolean',
|
||||||
|
sortInverted: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: '',
|
||||||
|
id: 'info',
|
||||||
|
Cell: ({ row }: any) => (
|
||||||
|
<FeatureResultInfoPopoverCell feature={row.original} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
import {Box, Chip, styled} from "@mui/material";
|
||||||
|
import {colors} from "../../../../../themes/colors";
|
||||||
|
import {ConditionallyRender} from "../../../../common/ConditionallyRender/ConditionallyRender";
|
||||||
|
import React, {ReactElement} from "react";
|
||||||
|
|
||||||
|
interface IResultChipProps {
|
||||||
|
enabled: boolean;
|
||||||
|
icon?: ReactElement;
|
||||||
|
label?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const StyledFalseChip = styled(Chip)(({ theme }) => ({
|
||||||
|
width: 80,
|
||||||
|
borderRadius: '5px',
|
||||||
|
border: `1px solid ${theme.palette.error.main}`,
|
||||||
|
backgroundColor: colors.red['200'],
|
||||||
|
['& .MuiChip-label']: {
|
||||||
|
color: theme.palette.error.main,
|
||||||
|
},
|
||||||
|
['& .MuiChip-icon']: {
|
||||||
|
color: theme.palette.error.main,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const StyledTrueChip = styled(Chip)(({ theme }) => ({
|
||||||
|
width: 80,
|
||||||
|
borderRadius: '5px',
|
||||||
|
border: `1px solid ${theme.palette.success.main}`,
|
||||||
|
backgroundColor: colors.green['100'],
|
||||||
|
['& .MuiChip-label']: {
|
||||||
|
color: theme.palette.success.main,
|
||||||
|
},
|
||||||
|
['& .MuiChip-icon']: {
|
||||||
|
color: theme.palette.success.main,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const ResultChip = ({ enabled, icon, label}: IResultChipProps) => {
|
||||||
|
return (
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={enabled}
|
||||||
|
show={<StyledTrueChip icon={Boolean(icon) ? icon : undefined} label={label}/>}
|
||||||
|
elseShow={<StyledFalseChip icon={Boolean(icon) ? icon : undefined} label={label}/>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import { Operator } from 'constants/operators';
|
import { Operator } from 'constants/operators';
|
||||||
|
import {ISegment} from "./segment";
|
||||||
|
|
||||||
export interface IFeatureStrategy {
|
export interface IFeatureStrategy {
|
||||||
id: string;
|
id: string;
|
||||||
@ -56,3 +57,20 @@ export interface IFeatureStrategySortOrder {
|
|||||||
id: string;
|
id: string;
|
||||||
sortOrder: number;
|
sortOrder: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface IPlaygroundFeatureStrategyConstraintResult extends IConstraint {
|
||||||
|
result: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPlaygroundFeatureStrategySegmentResult extends ISegment {
|
||||||
|
result: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPlaygroundFeatureStrategyResult {
|
||||||
|
type: string;
|
||||||
|
result: boolean;
|
||||||
|
id?: string;
|
||||||
|
constraints?: IPlaygroundFeatureStrategyConstraintResult[];
|
||||||
|
segments?: IPlaygroundFeatureStrategySegmentResult[];
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user