1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-23 00:22:19 +01:00

Fix/strategy UI improvements (#3766)

https://linear.app/unleash/issue/1-889/ui-adjustments


![image](https://github.com/Unleash/unleash/assets/2625371/e9d851e6-57b5-4deb-b3de-2c0c69fa71dd)

---------

Signed-off-by: andreas-unleash <andreas@getunleash.ai>
Co-authored-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
Tymoteusz Czech 2023-05-16 13:15:59 +02:00 committed by GitHub
parent e075d46f79
commit 0cb6174f75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 284 additions and 269 deletions

View File

@ -24,22 +24,34 @@ export const ChangeItemWrapper = styled(Box)({
});
const ChangeItemCreateEditWrapper = styled(Box)(({ theme }) => ({
display: 'flex',
justifyContent: 'space-between',
display: 'grid',
gridTemplateColumns: 'auto 40px',
gap: theme.spacing(1),
alignItems: 'center',
marginBottom: theme.spacing(2),
width: '100%',
}));
const ChangeItemInfo: FC = styled(Box)(({ theme }) => ({
display: 'flex',
display: 'grid',
gridTemplateColumns: '150px auto',
gridAutoFlow: 'column',
alignItems: 'center',
flexGrow: 1,
gap: theme.spacing(1),
}));
const hasNameField = (payload: unknown): payload is { name: string } =>
typeof payload === 'object' && payload !== null && 'name' in payload;
const DisabledEnabledState: VFC<{ disabled: boolean }> = ({ disabled }) => {
const DisabledEnabledState: VFC<{ show?: boolean; disabled: boolean }> = ({
show = true,
disabled,
}) => {
if (!show) {
return null;
}
if (disabled) {
return (
<Tooltip
@ -73,18 +85,16 @@ const EditHeader: VFC<{
}> = ({ wasDisabled = false, willBeDisabled = false }) => {
if (wasDisabled && willBeDisabled) {
return (
<Typography color="action.disabled">
Editing disabled strategy
</Typography>
<Typography color="action.disabled">Editing strategy:</Typography>
);
}
if (!wasDisabled && willBeDisabled) {
return <Typography color="error.dark">Editing strategy</Typography>;
return <Typography color="error.dark">Editing strategy:</Typography>;
}
if (wasDisabled && !willBeDisabled) {
return <Typography color="success.dark">Editing strategy</Typography>;
return <Typography color="success.dark">Editing strategy:</Typography>;
}
return <Typography>Editing strategy:</Typography>;
@ -128,14 +138,14 @@ export const StrategyChange: VFC<{
currentStrategy={currentStrategy}
/>
</StrategyTooltipLink>
<ConditionallyRender
condition={Boolean(
change.payload?.disabled === true
)}
show={<DisabledEnabledState disabled={true} />}
/>
<div>
<DisabledEnabledState
disabled
show={change.payload?.disabled === true}
/>
</div>
</ChangeItemInfo>
{discard}
<div>{discard}</div>
</ChangeItemCreateEditWrapper>
<StrategyExecution strategy={change.payload} />
</>
@ -144,9 +154,11 @@ export const StrategyChange: VFC<{
<ChangeItemWrapper>
<ChangeItemInfo>
<Typography
sx={theme => ({ color: theme.palette.error.main })}
sx={theme => ({
color: theme.palette.error.main,
})}
>
- Deleting strategy
- Deleting strategy:
</Typography>
{hasNameField(change.payload) && (
<StrategyTooltipLink change={change}>
@ -157,7 +169,7 @@ export const StrategyChange: VFC<{
</StrategyTooltipLink>
)}
</ChangeItemInfo>
{discard}
<div>{discard}</div>
</ChangeItemWrapper>
)}
{change.action === 'updateStrategy' && (
@ -178,9 +190,8 @@ export const StrategyChange: VFC<{
/>
</StrategyTooltipLink>
</ChangeItemInfo>
{discard}
<div>{discard}</div>
</ChangeItemCreateEditWrapper>
<StrategyExecution strategy={change.payload} />
<ConditionallyRender
condition={
change.payload?.disabled !==
@ -190,8 +201,7 @@ export const StrategyChange: VFC<{
<Typography
sx={{
marginTop: theme => theme.spacing(2),
paddingLeft: theme => theme.spacing(3),
paddingRight: theme => theme.spacing(3),
marginBottom: theme => theme.spacing(2),
...flexRow,
gap: theme => theme.spacing(1),
}}
@ -203,6 +213,7 @@ export const StrategyChange: VFC<{
</Typography>
}
/>
<StrategyExecution strategy={change.payload} />
</>
)}
</>

View File

@ -56,53 +56,59 @@ interface IStrategyTooltipLinkProps {
previousTitle?: string;
}
const StyledContainer: FC = styled('div')(({ theme }) => ({
display: 'grid',
gridAutoFlow: 'column',
gridTemplateColumns: 'auto 1fr',
gap: theme.spacing(1),
alignItems: 'center',
}));
const Truncated = styled('div')(() => ({
...textTruncated,
maxWidth: 500,
}));
export const StrategyTooltipLink: FC<IStrategyTooltipLinkProps> = ({
change,
previousTitle,
children,
}) => (
<>
<StyledContainer>
<GetFeatureStrategyIcon strategyName={change.payload.name} />
<ConditionallyRender
condition={Boolean(
previousTitle && previousTitle !== change.payload.title
)}
show={
<>
<Typography
component="s"
color="action.disabled"
sx={{
...textTruncated,
maxWidth: '100px',
}}
>
{previousTitle}
</Typography>{' '}
</>
}
/>
<TooltipLink
tooltip={children}
tooltipProps={{
maxWidth: 500,
maxHeight: 600,
}}
>
<Typography
component="span"
sx={{
...textTruncated,
maxWidth:
previousTitle === change.payload.title
? '300px'
: '200px',
display: 'block',
}}
>
{change.payload.title ||
formatStrategyName(change.payload.name)}
</Typography>
</TooltipLink>
</>
<Truncated>
<ConditionallyRender
condition={Boolean(
(previousTitle && previousTitle !== change.payload.title) ||
true
)}
show={
<Truncated>
<Typography component="s" color="text.secondary">
{previousTitle}
PREVIOUS consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
</Typography>{' '}
</Truncated>
}
/>
<Truncated>
<TooltipLink
tooltip={children}
tooltipProps={{
maxWidth: 500,
maxHeight: 600,
}}
>
<Typography component="span">
{change.payload.title ||
formatStrategyName(change.payload.name)}
lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua.
</Typography>
</TooltipLink>
</Truncated>
</Truncated>
</StyledContainer>
);

View File

@ -81,7 +81,7 @@ const StyledHeader = styled('div', {
fontWeight: theme.typography.fontWeightMedium,
paddingLeft: draggable ? theme.spacing(1) : theme.spacing(2),
color: disabled
? theme.palette.action.disabled
? theme.palette.text.secondary
: theme.palette.text.primary,
})
);
@ -139,7 +139,7 @@ export const StrategyItemContainer: FC<IStrategyItemContainerProps> = ({
/>
<StyledHeaderContainer>
<StringTruncator
maxWidth="150"
maxWidth="400"
maxLength={15}
text={formatStrategyName(
uiConfig?.flags?.strategyImprovements

View File

@ -211,16 +211,6 @@ export const FeatureStrategyForm = ({
/>
</FeatureStrategyEnabled>
<StyledHr />
<ConditionallyRender
condition={Boolean(uiConfig.flags.SE)}
show={
<FeatureStrategySegment
segments={segments}
setSegments={setSegments}
projectId={projectId}
/>
}
/>
<ConditionallyRender
condition={Boolean(uiConfig?.flags?.strategyImprovements)}
show={
@ -235,6 +225,16 @@ export const FeatureStrategyForm = ({
/>
}
/>
<ConditionallyRender
condition={Boolean(uiConfig.flags.SE)}
show={
<FeatureStrategySegment
segments={segments}
setSegments={setSegments}
projectId={projectId}
/>
}
/>
<FeatureStrategyConstraints
projectId={feature.project}
environmentId={environmentId}

View File

@ -24,6 +24,7 @@ interface IFeatureStrategyRemoveProps {
strategyId: string;
disabled?: boolean;
icon?: boolean;
text?: boolean;
}
interface IFeatureStrategyRemoveDialogueProps {
@ -163,6 +164,7 @@ export const FeatureStrategyRemove = ({
strategyId,
disabled,
icon,
text,
}: IFeatureStrategyRemoveProps) => {
const [openDialogue, setOpenDialogue] = useState(false);
@ -197,6 +199,18 @@ export const FeatureStrategyRemove = ({
type="button"
>
<Delete />
<ConditionallyRender
condition={Boolean(text)}
show={
<Typography
variant={'body1'}
color={'text.secondary'}
sx={{ ml: theme => theme.spacing(1) }}
>
Remove
</Typography>
}
/>
</PermissionIconButton>
}
elseShow={

View File

@ -1,5 +1,5 @@
import { VFC, useState } from 'react';
import { Alert } from '@mui/material';
import { Alert, Typography } from '@mui/material';
import BlockIcon from '@mui/icons-material/Block';
import TrackChangesIcon from '@mui/icons-material/TrackChanges';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
@ -46,6 +46,18 @@ const DisableStrategy: VFC<IDisableEnableStrategyProps> = ({ ...props }) => {
type="button"
>
<BlockIcon />
<ConditionallyRender
condition={Boolean(props.text)}
show={
<Typography
variant={'body1'}
color={'text.secondary'}
sx={{ ml: theme => theme.spacing(1) }}
>
Disable
</Typography>
}
/>
</PermissionIconButton>
<Dialogue
title={
@ -111,6 +123,18 @@ const EnableStrategy: VFC<IDisableEnableStrategyProps> = ({ ...props }) => {
type="button"
>
<TrackChangesIcon />
<ConditionallyRender
condition={Boolean(props.text)}
show={
<Typography
variant={'body1'}
color={'text.secondary'}
sx={{ ml: theme => theme.spacing(1) }}
>
Disable
</Typography>
}
/>
</PermissionIconButton>
<Dialogue
title={

View File

@ -5,4 +5,5 @@ export interface IDisableEnableStrategyProps {
featureId: string;
environmentId: string;
strategy: IFeatureStrategy;
text?: boolean;
}

View File

@ -0,0 +1,134 @@
import React, { SyntheticEvent } from 'react';
import {
Avatar,
Box,
IconButton,
ListItem,
Menu,
MenuItem,
styled,
Tooltip,
Typography,
} from '@mui/material';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import { IFeatureStrategy } from '../../../../../../../../../../interfaces/strategy';
import { FeatureStrategyRemove } from '../../../../../../../../FeatureStrategy/FeatureStrategyRemove/FeatureStrategyRemove';
import { DisableEnableStrategy } from '../DisableEnableStrategy/DisableEnableStrategy';
export interface IRemoveStrategyMenuProps {
projectId: string;
featureId: string;
environmentId: string;
strategy: IFeatureStrategy;
}
const StyledContainer = styled(ListItem)(({ theme }) => ({
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
minWidth: 'fit-content',
padding: theme.spacing(0, 2),
}));
const RemoveStrategyMenu = ({
projectId,
strategy,
featureId,
environmentId,
}: IRemoveStrategyMenuProps) => {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = (event: SyntheticEvent) => {
setAnchorEl(null);
event.stopPropagation();
};
return (
<>
<Box
sx={{
display: 'flex',
alignItems: 'center',
textAlign: 'center',
}}
>
<Tooltip title="More actions">
<IconButton
onClick={handleClick}
size="small"
aria-controls={open ? 'actions-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
>
<MoreVertIcon sx={{ width: 32, height: 32 }} />
</IconButton>
</Tooltip>
</Box>
<Menu
anchorEl={anchorEl}
id="actions-menu"
open={open}
onClose={handleClose}
onClick={handleClose}
PaperProps={{
elevation: 0,
sx: {
overflow: 'visible',
filter: 'drop-shadow(0px 2px 8px rgba(0,0,0,0.32))',
mt: 1.5,
pl: 0.5,
minWidth: 'fit-content',
justifyContent: 'center',
li: {
pl: 0,
},
'&:before': {
content: '""',
display: 'block',
position: 'absolute',
top: 0,
right: 14,
width: 10,
height: 10,
bgcolor: 'background.paper',
transform: 'translateY(-50%) rotate(45deg)',
zIndex: 0,
},
},
}}
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
>
<MenuItem
component={() => (
<StyledContainer>
<DisableEnableStrategy
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
strategy={strategy}
text
/>
</StyledContainer>
)}
/>
<MenuItem
component={() => (
<FeatureStrategyRemove
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
strategyId={strategy.id}
text
icon
/>
)}
/>
</Menu>
</>
);
};
export default RemoveStrategyMenu;

View File

@ -14,6 +14,7 @@ import { CopyStrategyIconMenu } from './CopyStrategyIconMenu/CopyStrategyIconMen
import { StrategyItemContainer } from 'component/common/StrategyItemContainer/StrategyItemContainer';
import { DisableEnableStrategy } from './DisableEnableStrategy/DisableEnableStrategy';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import RemoveStrategyMenu from './RemoveStrategyMenu/RemoveStrategyMenu';
interface IStrategyItemProps {
environmentId: string;
@ -84,20 +85,22 @@ export const StrategyItem: FC<IStrategyItemProps> = ({
uiConfig?.flags?.strategyImprovements
)}
show={() => (
<DisableEnableStrategy
<RemoveStrategyMenu
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
strategy={strategy}
/>
)}
/>
<FeatureStrategyRemove
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
strategyId={strategy.id}
icon
elseShow={() => (
<FeatureStrategyRemove
projectId={projectId}
featureId={featureId}
environmentId={environmentId}
strategyId={strategy.id}
icon
/>
)}
/>
</>
}

View File

@ -23,7 +23,6 @@ import useToast from 'hooks/useToast';
import { EnvironmentVariantsCopyFrom } from './EnvironmentVariantsCopyFrom/EnvironmentVariantsCopyFrom';
import { PushVariantsButton } from './PushVariantsButton/PushVariantsButton';
import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
@ -42,7 +41,6 @@ const StyledButtonContainer = styled('div')(({ theme }) => ({
}));
export const FeatureEnvironmentVariants = () => {
const { uiConfig } = useUiConfig();
const { setToastData, setToastApiError } = useToast();
const theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));

View File

@ -3,7 +3,6 @@ import useProject from 'hooks/api/getters/useProject/useProject';
import useLoading from 'hooks/useLoading';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import {
StyledColumn,
StyledDiv,
StyledFavoriteIconButton,
StyledHeader,
@ -13,8 +12,6 @@ import {
StyledSeparator,
StyledTab,
StyledTabContainer,
StyledText,
StyledTitle,
StyledTopRow,
} from './Project.styles';
import { Tabs } from '@mui/material';

View File

@ -1,75 +0,0 @@
import { Box, styled, Typography } from '@mui/material';
import { Link } from 'react-router-dom';
import PercentageCircle from 'component/common/PercentageCircle/PercentageCircle';
import { flexRow } from 'themes/themeStyles';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import { StyledProjectInfoWidgetContainer } from './ProjectInfo.styles';
interface ILegacyHealthWidgetProps {
projectId: string;
health: number;
total?: number;
stale?: number;
}
const StyledParagraphEmphasizedText = styled('p')(({ theme }) => ({
fontSize: '1.5rem',
[theme.breakpoints.down('md')]: {
fontSize: theme.fontSizes.bodySize,
marginBottom: theme.spacing(4),
},
}));
const StyledDivPercentageContainer = styled('div')(() => ({
display: 'flex',
justifyContent: 'center',
}));
const StyledLink = styled(Link)(({ theme }) => ({
textDecoration: 'none',
...flexRow,
justifyContent: 'center',
color: theme.palette.primary.main,
[theme.breakpoints.down('md')]: {
position: 'absolute',
bottom: theme.spacing(1.5),
right: theme.spacing(1.5),
},
}));
const StyledSpanLinkText = styled('p')(({ theme }) => ({
[theme.breakpoints.down('md')]: {
display: 'none',
},
}));
const StyledArrowIcon = styled(ArrowForwardIcon)(({ theme }) => ({
color: theme.palette.primary.main,
marginLeft: theme.spacing(1),
}));
/**
* @deprecated
*/
export const LegacyHealthWidget = ({
projectId,
health,
}: ILegacyHealthWidgetProps) => (
<StyledProjectInfoWidgetContainer>
<StyledDivPercentageContainer>
<PercentageCircle percentage={health} />
</StyledDivPercentageContainer>
<Typography data-loading sx={{ marginTop: theme => theme.spacing(2) }}>
Overall health rating
</Typography>
<Box sx={{ marginBottom: theme => theme.spacing(2.5) }}>
<StyledParagraphEmphasizedText data-loading>
{health}%
</StyledParagraphEmphasizedText>
</Box>
<StyledLink data-loading to={`/projects/${projectId}/health`}>
<StyledSpanLinkText data-loading>view more </StyledSpanLinkText>
<StyledArrowIcon data-loading />
</StyledLink>
</StyledProjectInfoWidgetContainer>
);

View File

@ -1,93 +0,0 @@
import { Link } from 'react-router-dom';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import { flexRow } from 'themes/themeStyles';
import { styled } from '@mui/material';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
const StyledDivInfoContainer = styled('div')(({ theme }) => ({
textAlign: 'center',
backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadiusLarge,
width: '100%',
padding: theme.spacing(3, 2, 3, 2),
[theme.breakpoints.down('md')]: {
...flexRow,
flexDirection: 'column',
justifyContent: 'center',
fontSize: theme.fontSizes.smallBody,
position: 'relative',
padding: theme.spacing(1.5),
},
}));
const StyledParagraphSubtitle = styled('p')(({ theme }) => ({
marginBottom: theme.spacing(2),
}));
const StyledParagraphEmphasizedText = styled('p')(({ theme }) => ({
fontSize: '1.5rem',
marginBottom: theme.spacing(2),
[theme.breakpoints.down('md')]: {
fontSize: theme.fontSizes.bodySize,
marginBottom: theme.spacing(4),
},
}));
const StyledSpanLinkText = styled('p')(({ theme }) => ({
[theme.breakpoints.down('md')]: {
display: 'none',
},
}));
const StyledLink = styled(Link)(({ theme }) => ({
textDecoration: 'none',
...flexRow,
justifyContent: 'center',
color: theme.palette.primary.main,
[theme.breakpoints.down('md')]: {
position: 'absolute',
right: theme.spacing(1.5),
bottom: theme.spacing(1.5),
},
}));
const StyledArrowIcon = styled(ArrowForwardIcon)(({ theme }) => ({
color: theme.palette.primary.main,
marginLeft: theme.spacing(1),
}));
interface ILegacyProjectMembersWidgetProps {
projectId: string;
memberCount: number;
}
/**
* @deprecated
*/
export const LegacyProjectMembersWidget = ({
projectId,
memberCount,
}: ILegacyProjectMembersWidgetProps) => {
const { uiConfig } = useUiConfig();
let link = `/admin/users`;
if (uiConfig?.versionInfo?.current?.enterprise) {
link = `/projects/${projectId}/settings/access`;
}
return (
<StyledDivInfoContainer>
<StyledParagraphSubtitle data-loading>
Project members
</StyledParagraphSubtitle>
<StyledParagraphEmphasizedText data-loading>
{memberCount}
</StyledParagraphEmphasizedText>
<StyledLink data-loading to={link}>
<StyledSpanLinkText data-loading>view more </StyledSpanLinkText>
<StyledArrowIcon data-loading />
</StyledLink>
</StyledDivInfoContainer>
);
};

View File

@ -10,8 +10,6 @@ import { ProjectMembersWidget } from './ProjectMembersWidget';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { ChangeRequestsWidget } from './ChangeRequestsWidget';
import { flexRow } from 'themes/themeStyles';
import { LegacyHealthWidget } from './LegacyHealthWidget';
import { LegacyProjectMembersWidget } from './LegacyProjectMembersWidget';
import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
interface IProjectInfoProps {
@ -48,7 +46,7 @@ const ProjectInfo = ({
features,
stats,
}: IProjectInfoProps) => {
const { uiConfig, isEnterprise } = useUiConfig();
const { isEnterprise } = useUiConfig();
const theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
const { isChangeRequestConfiguredInAnyEnv } = useChangeRequestsEnabled(id);

View File

@ -42,7 +42,6 @@ const ProjectOverview = () => {
project;
usePageTitle(`Project overview ${projectName}`);
const { setLastViewed } = useLastViewedProject();
const { uiConfig } = useUiConfig();
useEffect(() => {
setLastViewed(projectId);

View File

@ -3,11 +3,11 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useNavigate } from 'react-router-dom';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { useStrategy } from 'hooks/api/getters/useStrategy/useStrategy';
import React, { useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { formatUnknownError } from 'utils/formatUnknownError';
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
import { UPDATE_FEATURE_STRATEGY } from 'component/providers/AccessProvider/permissions';
import { IFeatureStrategy, IStrategy } from 'interfaces/strategy';
import { IStrategy } from 'interfaces/strategy';
import { useRequiredQueryParam } from 'hooks/useRequiredQueryParam';
import { ISegment } from 'interfaces/segment';
import { useFormErrors } from 'hooks/useFormErrors';
@ -42,7 +42,7 @@ const EditDefaultStrategy = ({ strategy }: EditDefaultStrategyProps) => {
const { unleashUrl } = uiConfig;
const navigate = useNavigate();
const [previousTitle, setPreviousTitle] = useState<string>('');
const [previousTitle] = useState<string>('');
const { trackEvent } = usePlausibleTracker();
const trackTitle = (title: string = '') => {

View File

@ -27,13 +27,11 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
import { Search } from 'component/common/Search/Search';
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useOptionalPathParam } from 'hooks/useOptionalPathParam';
export const SegmentTable = () => {
const projectId = useOptionalPathParam('projectId');
const { segments, loading } = useSegments();
const { uiConfig } = useUiConfig();
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
const [initialState] = useState({
sortBy: [{ id: 'createdAt' }],