From 56c9584bb6e036f6264276c2ce2aba21407c1f34 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Thu, 6 Feb 2025 14:55:59 +0100 Subject: [PATCH] feat: move timeline to panel (#9243) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves the event timeline to the personal dashboard from the header when the `frontendHeaderRedesign` flag is active. When the flag is active, it also: - hides the event timeline and corresponding button in the header - renders the environment selector next to the time selector instead of at the other end of the header ![image](https://github.com/user-attachments/assets/cccd8f07-d42a-4180-807f-20937019442d) --------- Co-authored-by: Nuno Góis --- .../EventTimelineHeader.tsx | 93 ++++++++++--------- .../layout/MainLayout/MainLayout.tsx | 5 +- frontend/src/component/menu/Header/Header.tsx | 5 +- .../personalDashboard/PersonalDashboard.tsx | 51 ++++++++++ .../personalDashboard/SharedComponents.tsx | 10 +- .../personalDashboard/useDashboardState.ts | 17 +++- 6 files changed, 131 insertions(+), 50 deletions(-) diff --git a/frontend/src/component/events/EventTimeline/EventTimelineHeader/EventTimelineHeader.tsx b/frontend/src/component/events/EventTimeline/EventTimelineHeader/EventTimelineHeader.tsx index e29ee11718..5f6371cb39 100644 --- a/frontend/src/component/events/EventTimeline/EventTimelineHeader/EventTimelineHeader.tsx +++ b/frontend/src/component/events/EventTimeline/EventTimelineHeader/EventTimelineHeader.tsx @@ -12,8 +12,9 @@ import { timeSpanOptions } from '../EventTimelineProvider'; import CloseIcon from '@mui/icons-material/Close'; import { useEventTimelineContext } from '../EventTimelineContext'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; -import { EventTimelineHeaderTip } from './EventTimelineHeaderTip'; import { HelpIcon } from 'component/common/HelpIcon/HelpIcon'; +import { EventTimelineHeaderTip } from './EventTimelineHeaderTip'; +import { useUiFlag } from 'hooks/useUiFlag'; const StyledCol = styled('div')(({ theme }) => ({ display: 'flex', @@ -49,6 +50,7 @@ export const EventTimelineHeader = ({ const { timeSpan, environment, setOpen, setTimeSpan, setEnvironment } = useEventTimelineContext(); const { environments } = useEnvironments(); + const frontendHeaderRefactor = useUiFlag('frontendHeaderRedesign'); const activeEnvironments = useMemo( () => environments.filter(({ enabled }) => enabled), @@ -65,6 +67,33 @@ export const EventTimelineHeader = ({ } }, [activeEnvironments]); + const EnvironmentFilter = () => ( + 0} + show={() => ( + + setEnvironment( + environments.find( + ({ name }) => name === e.target.value, + ) || environments[0], + ) + } + > + {environments.map(({ name }) => ( + + {name} + + ))} + + )} + /> + ); + return ( <> @@ -92,50 +121,30 @@ export const EventTimelineHeader = ({ ))} + {frontendHeaderRefactor && } - - - 0} - show={() => ( - + + + + - setEnvironment( - environments.find( - ({ name }) => name === e.target.value, - ) || environments[0], - ) - } + onClick={() => { + trackEvent('event-timeline', { + props: { + eventType: 'close', + }, + }); + setOpen(false); + }} > - {environments.map(({ name }) => ( - - {name} - - ))} - - )} - /> - - { - trackEvent('event-timeline', { - props: { - eventType: 'close', - }, - }); - setOpen(false); - }} - > - - - - + + + + + )} ); }; diff --git a/frontend/src/component/layout/MainLayout/MainLayout.tsx b/frontend/src/component/layout/MainLayout/MainLayout.tsx index f743bdc40d..f977689e57 100644 --- a/frontend/src/component/layout/MainLayout/MainLayout.tsx +++ b/frontend/src/component/layout/MainLayout/MainLayout.tsx @@ -150,7 +150,10 @@ export const MainLayout = forwardRef( show={
} /> - + } + /> diff --git a/frontend/src/component/menu/Header/Header.tsx b/frontend/src/component/menu/Header/Header.tsx index 7aa36e2d5e..d79d3cabba 100644 --- a/frontend/src/component/menu/Header/Header.tsx +++ b/frontend/src/component/menu/Header/Header.tsx @@ -199,7 +199,10 @@ const Header = () => { - + } + /> ({ display: 'flex', @@ -109,6 +113,7 @@ export const PersonalDashboard = () => { const { splash } = useAuthSplash(); const { isOss } = useUiConfig(); const name = user?.name || ''; + const showTimelinePanel = useUiFlag('frontendHeaderRedesign'); usePageTitle(name ? `Dashboard: ${name}` : 'Dashboard'); @@ -125,8 +130,11 @@ export const PersonalDashboard = () => { toggleSectionState, expandFlags, expandProjects, + expandTimeline, } = useDashboardState(projects, personalDashboard?.flags ?? []); + const signalsLink = '/integrations/signals'; + const [welcomeDialog, setWelcomeDialog] = useLocalStorageState< 'open' | 'closed' >( @@ -175,6 +183,49 @@ export const PersonalDashboard = () => { + {showTimelinePanel && ( + toggleSectionState('timeline')} + > + + } + id='timeline-panel-header' + aria-controls='timeline-panel-content' + > + + + Timeline of events + + + Overview of recent activities across all + projects in Unleash. Make debugging easier and{' '} + { + trackEvent('event-timeline', { + props: { + eventType: 'signals clicked', + }, + }); + }} + > + include external signals + {' '} + to get a fuller overview. + + + + + + + + + + )} ({ + padding: theme.spacing(2, 4), +})); + +export const GridItem = styled(AccordionContent, { shouldForwardProp: (prop) => !['gridArea'].includes(prop.toString()), })<{ gridArea: string }>(({ theme, gridArea }) => ({ - padding: theme.spacing(2, 4), maxHeight: '100%', overflowY: 'auto', gridArea, diff --git a/frontend/src/component/personalDashboard/useDashboardState.ts b/frontend/src/component/personalDashboard/useDashboardState.ts index 11eaee8908..c9652063e3 100644 --- a/frontend/src/component/personalDashboard/useDashboardState.ts +++ b/frontend/src/component/personalDashboard/useDashboardState.ts @@ -14,6 +14,7 @@ export const useDashboardState = ( activeFlag: PersonalDashboardSchemaFlagsItem | undefined; expandProjects: boolean; expandFlags: boolean; + expandTimeline: boolean; }; const defaultState: State = { @@ -21,6 +22,7 @@ export const useDashboardState = ( activeFlag: undefined, expandProjects: true, expandFlags: true, + expandTimeline: false, }; const [state, setState] = useLocalStorageState( @@ -76,8 +78,18 @@ export const useDashboardState = ( }); }; - const toggleSectionState = (section: 'flags' | 'projects') => { - const property = section === 'flags' ? 'expandFlags' : 'expandProjects'; + const toggleSectionState = (section: 'flags' | 'projects' | 'timeline') => { + const getProperty = () => { + switch (section) { + case 'flags': + return 'expandFlags'; + case 'projects': + return 'expandProjects'; + case 'timeline': + return 'expandTimeline'; + } + }; + const property = getProperty(); updateState({ [property]: !(state[property] ?? true), }); @@ -90,6 +102,7 @@ export const useDashboardState = ( setActiveProject, expandFlags: state.expandFlags ?? true, expandProjects: state.expandProjects ?? true, + expandTimeline: state.expandTimeline ?? false, toggleSectionState, }; };