From 0cb6174f7515f06615b1a3537e4565a5f82d6785 Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Tue, 16 May 2023 13:15:59 +0200 Subject: [PATCH] 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 Co-authored-by: andreas-unleash --- .../Changes/Change/StrategyChange.tsx | 57 +++++--- .../StrategyTooltipLink.tsx | 92 ++++++------ .../StrategyItemContainer.tsx | 4 +- .../FeatureStrategyForm.tsx | 20 +-- .../FeatureStrategyRemove.tsx | 14 ++ .../DisableEnableStrategy.tsx | 26 +++- .../IDisableEnableStrategyProps.ts | 1 + .../RemoveStrategyMenu/RemoveStrategyMenu.tsx | 134 ++++++++++++++++++ .../StrategyItem/StrategyItem.tsx | 19 +-- .../FeatureEnvironmentVariants.tsx | 2 - .../src/component/project/Project/Project.tsx | 3 - .../ProjectInfo/LegacyHealthWidget.tsx | 75 ---------- .../LegacyProjectMembersWidget.tsx | 93 ------------ .../Project/ProjectInfo/ProjectInfo.tsx | 4 +- .../project/Project/ProjectOverview.tsx | 1 - .../EditDefaultStrategy.tsx | 6 +- .../src/component/segments/SegmentTable.tsx | 2 - 17 files changed, 284 insertions(+), 269 deletions(-) create mode 100644 frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/RemoveStrategyMenu/RemoveStrategyMenu.tsx delete mode 100644 frontend/src/component/project/Project/ProjectInfo/LegacyHealthWidget.tsx delete mode 100644 frontend/src/component/project/Project/ProjectInfo/LegacyProjectMembersWidget.tsx diff --git a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx index f3da29ec8c..f238429158 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/Changes/Change/StrategyChange.tsx @@ -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 ( = ({ wasDisabled = false, willBeDisabled = false }) => { if (wasDisabled && willBeDisabled) { return ( - - Editing disabled strategy - + Editing strategy: ); } if (!wasDisabled && willBeDisabled) { - return Editing strategy; + return Editing strategy:; } if (wasDisabled && !willBeDisabled) { - return Editing strategy; + return Editing strategy:; } return Editing strategy:; @@ -128,14 +138,14 @@ export const StrategyChange: VFC<{ currentStrategy={currentStrategy} /> - } - /> +
+ +
- {discard} +
{discard}
@@ -144,9 +154,11 @@ export const StrategyChange: VFC<{ ({ color: theme.palette.error.main })} + sx={theme => ({ + color: theme.palette.error.main, + })} > - - Deleting strategy + - Deleting strategy: {hasNameField(change.payload) && ( @@ -157,7 +169,7 @@ export const StrategyChange: VFC<{ )} - {discard} +
{discard}
)} {change.action === 'updateStrategy' && ( @@ -178,9 +190,8 @@ export const StrategyChange: VFC<{ /> - {discard} +
{discard}
- 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<{ } /> + )} diff --git a/frontend/src/component/changeRequest/ChangeRequest/StrategyTooltipLink/StrategyTooltipLink.tsx b/frontend/src/component/changeRequest/ChangeRequest/StrategyTooltipLink/StrategyTooltipLink.tsx index 5c162d7a47..dfa54a6c27 100644 --- a/frontend/src/component/changeRequest/ChangeRequest/StrategyTooltipLink/StrategyTooltipLink.tsx +++ b/frontend/src/component/changeRequest/ChangeRequest/StrategyTooltipLink/StrategyTooltipLink.tsx @@ -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 = ({ change, previousTitle, children, }) => ( - <> + - - - {previousTitle} - {' '} - - } - /> - - - {change.payload.title || - formatStrategyName(change.payload.name)} - - - + + + + {previousTitle} + PREVIOUS consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. + {' '} + + } + /> + + + + {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. + + + + + ); diff --git a/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx b/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx index b024f419c0..77b722affb 100644 --- a/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx +++ b/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx @@ -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 = ({ /> - - } - /> } /> + + } + /> { const [openDialogue, setOpenDialogue] = useState(false); @@ -197,6 +199,18 @@ export const FeatureStrategyRemove = ({ type="button" > + theme.spacing(1) }} + > + Remove + + } + /> } elseShow={ diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/DisableEnableStrategy/DisableEnableStrategy.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/DisableEnableStrategy/DisableEnableStrategy.tsx index e7e457fa66..ca9807c213 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/DisableEnableStrategy/DisableEnableStrategy.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/DisableEnableStrategy/DisableEnableStrategy.tsx @@ -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 = ({ ...props }) => { type="button" > + theme.spacing(1) }} + > + Disable + + } + /> = ({ ...props }) => { type="button" > + theme.spacing(1) }} + > + Disable + + } + /> ({ + 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); + const open = Boolean(anchorEl); + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = (event: SyntheticEvent) => { + setAnchorEl(null); + event.stopPropagation(); + }; + return ( + <> + + + + + + + + + ( + + + + )} + /> + ( + + )} + /> + + + ); +}; + +export default RemoveStrategyMenu; diff --git a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.tsx b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.tsx index d4baf0557c..506556e0d6 100644 --- a/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureOverview/FeatureOverviewEnvironments/FeatureOverviewEnvironment/EnvironmentAccordionBody/StrategyDraggableItem/StrategyItem/StrategyItem.tsx @@ -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 = ({ uiConfig?.flags?.strategyImprovements )} show={() => ( - )} - /> - ( + + )} /> } diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/FeatureEnvironmentVariants.tsx b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/FeatureEnvironmentVariants.tsx index b242f8f43b..3a137aa7fb 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/FeatureEnvironmentVariants.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/FeatureEnvironmentVariants.tsx @@ -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')); diff --git a/frontend/src/component/project/Project/Project.tsx b/frontend/src/component/project/Project/Project.tsx index 626e32b447..4ad9086c18 100644 --- a/frontend/src/component/project/Project/Project.tsx +++ b/frontend/src/component/project/Project/Project.tsx @@ -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'; diff --git a/frontend/src/component/project/Project/ProjectInfo/LegacyHealthWidget.tsx b/frontend/src/component/project/Project/ProjectInfo/LegacyHealthWidget.tsx deleted file mode 100644 index 6a7e231543..0000000000 --- a/frontend/src/component/project/Project/ProjectInfo/LegacyHealthWidget.tsx +++ /dev/null @@ -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) => ( - - - - - theme.spacing(2) }}> - Overall health rating - - theme.spacing(2.5) }}> - - {health}% - - - - view more - - - -); diff --git a/frontend/src/component/project/Project/ProjectInfo/LegacyProjectMembersWidget.tsx b/frontend/src/component/project/Project/ProjectInfo/LegacyProjectMembersWidget.tsx deleted file mode 100644 index 2692bd789a..0000000000 --- a/frontend/src/component/project/Project/ProjectInfo/LegacyProjectMembersWidget.tsx +++ /dev/null @@ -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 ( - - - Project members - - - {memberCount} - - - view more - - - - ); -}; diff --git a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx index e8ab9a33c2..161551275b 100644 --- a/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx +++ b/frontend/src/component/project/Project/ProjectInfo/ProjectInfo.tsx @@ -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); diff --git a/frontend/src/component/project/Project/ProjectOverview.tsx b/frontend/src/component/project/Project/ProjectOverview.tsx index 50b4a88aa3..74ebbf742b 100644 --- a/frontend/src/component/project/Project/ProjectOverview.tsx +++ b/frontend/src/component/project/Project/ProjectOverview.tsx @@ -42,7 +42,6 @@ const ProjectOverview = () => { project; usePageTitle(`Project overview – ${projectName}`); const { setLastViewed } = useLastViewedProject(); - const { uiConfig } = useUiConfig(); useEffect(() => { setLastViewed(projectId); diff --git a/frontend/src/component/project/Project/ProjectSettings/ProjectDefaultStrategySettings/ProjectEnvironment/ProjectEnvironmentDefaultStrategy/EditDefaultStrategy.tsx b/frontend/src/component/project/Project/ProjectSettings/ProjectDefaultStrategySettings/ProjectEnvironment/ProjectEnvironmentDefaultStrategy/EditDefaultStrategy.tsx index 1e5e0e550d..247a01c6fc 100644 --- a/frontend/src/component/project/Project/ProjectSettings/ProjectDefaultStrategySettings/ProjectEnvironment/ProjectEnvironmentDefaultStrategy/EditDefaultStrategy.tsx +++ b/frontend/src/component/project/Project/ProjectSettings/ProjectDefaultStrategySettings/ProjectEnvironment/ProjectEnvironmentDefaultStrategy/EditDefaultStrategy.tsx @@ -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(''); + const [previousTitle] = useState(''); const { trackEvent } = usePlausibleTracker(); const trackTitle = (title: string = '') => { diff --git a/frontend/src/component/segments/SegmentTable.tsx b/frontend/src/component/segments/SegmentTable.tsx index fbd31bbe51..b469d07cde 100644 --- a/frontend/src/component/segments/SegmentTable.tsx +++ b/frontend/src/component/segments/SegmentTable.tsx @@ -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' }],