From 513d60c14d4a8c81bdd569f848118aae8fc49448 Mon Sep 17 00:00:00 2001 From: andreas-unleash Date: Thu, 14 Mar 2024 11:33:30 +0200 Subject: [PATCH] Feat: sticky insights header and widget tooltip icon (#6537) What it says on the tin Closes # [1-2182](https://linear.app/unleash/issue/1-2182/sticky-header-on-scroll) Screenshot 2024-03-14 at 10 47 32 https://github.com/Unleash/unleash/assets/104830839/f5249fd6-a4cc-4e52-9b01-89ef3cbeb47c --------- Signed-off-by: andreas-unleash --- .../executiveDashboard/ExecutiveDashboard.tsx | 30 +++++++++++++++++-- .../DashboardHeader/DashboardHeader.tsx | 3 +- .../LineChart/createChartOptions.ts | 4 ++- .../components/Widget/Widget.tsx | 7 ++++- .../HealthStats/HealthStats.tsx | 6 ++-- frontend/src/themes/theme.ts | 2 +- 6 files changed, 42 insertions(+), 10 deletions(-) diff --git a/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx b/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx index 407ccf5805..e9f924bec1 100644 --- a/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx +++ b/frontend/src/component/executiveDashboard/ExecutiveDashboard.tsx @@ -1,4 +1,4 @@ -import { VFC } from 'react'; +import { useState, VFC } from 'react'; import { Box, styled } from '@mui/material'; import { ArrayParam, withDefault } from 'use-query-params'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; @@ -45,7 +45,19 @@ const ChartWidget = styled(Widget)(({ theme }) => ({ }, })); +const StickyWrapper = styled(Box)<{ scrolled?: boolean }>( + ({ theme, scrolled }) => ({ + position: 'sticky', + top: 0, + zIndex: 1000, + padding: scrolled ? theme.spacing(2, 0) : theme.spacing(0, 0, 2), + background: theme.palette.background.application, + transition: 'padding 0.3s ease', + }), +); + export const ExecutiveDashboard: VFC = () => { + const [scrolled, setScrolled] = useState(false); const { executiveDashboardData, loading, error } = useExecutiveDashboard(); const stateConfig = { projects: withDefault(ArrayParam, [allOption.id]), @@ -72,9 +84,21 @@ export const ExecutiveDashboard: VFC = () => { const summary = useFilteredFlagsSummary(projectsData); const isOneProjectSelected = projects.length === 1; + const handleScroll = () => { + if (!scrolled && window.scrollY > 0) { + setScrolled(true); + } else if (scrolled && window.scrollY === 0) { + setScrolled(false); + } + }; + + if (typeof window !== 'undefined') { + window.addEventListener('scroll', handleScroll); + } + return ( <> - ({ paddingBottom: theme.spacing(4) })}> + { /> } /> - + ({ padding: theme.spacing(3), @@ -29,7 +30,11 @@ export const Widget: FC<{ {title} } + show={ + + + + } /> {children} diff --git a/frontend/src/component/executiveDashboard/componentsStat/HealthStats/HealthStats.tsx b/frontend/src/component/executiveDashboard/componentsStat/HealthStats/HealthStats.tsx index c2f7b5a672..d6c35f11f9 100644 --- a/frontend/src/component/executiveDashboard/componentsStat/HealthStats/HealthStats.tsx +++ b/frontend/src/component/executiveDashboard/componentsStat/HealthStats/HealthStats.tsx @@ -73,7 +73,7 @@ export const HealthStats: VFC = ({ x={206} y={72} fill={theme.palette.charts.health.text} - fontSize={12} + fontSize={13} textAnchor='middle' > Healthy @@ -100,7 +100,7 @@ export const HealthStats: VFC = ({ x={53} y={81} fill={theme.palette.charts.health.text} - fontSize={12} + fontSize={13} textAnchor='middle' > Stale @@ -127,7 +127,7 @@ export const HealthStats: VFC = ({ x={144} y={232} fill={theme.palette.charts.health.text} - fontSize={12} + fontSize={13} textAnchor='middle' > diff --git a/frontend/src/themes/theme.ts b/frontend/src/themes/theme.ts index 94c70a1f21..280be06356 100644 --- a/frontend/src/themes/theme.ts +++ b/frontend/src/themes/theme.ts @@ -283,7 +283,7 @@ export const theme = { title: colors.grey[50], healthy: colors.purple[800], stale: colors.red[800], - potentiallyStale: colors.orange[800], + potentiallyStale: colors.orange[900], gradientStale: colors.red[300], gradientPotentiallyStale: colors.orange[500], },