mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	https://linear.app/unleash/issue/2-2703/align-with-ux Timeline UI/UX improvements after sync with UX, including: - Added some spacing between each event in the grouping tooltip - Aligned the x events occurred header with filter dropdown - Improved the strategy icon somewhat so it doesn't look as off center - New timeline icon - Improve icon position relative to timestamp on each event in the grouping tooltip - Changed text color in dropdowns to a lighter gray - Removed bold formatting in tooltip - Adjusted paddings and margins - Added close button - Added shadow - Added left border There are a few details missing, which will be tackled in separate PRs.  --------- Co-authored-by: Nuno Góis <github@nunogois.com>
		
			
				
	
	
		
			135 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import {
 | |
|     IconButton,
 | |
|     MenuItem,
 | |
|     styled,
 | |
|     TextField,
 | |
|     Tooltip,
 | |
| } from '@mui/material';
 | |
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
 | |
| import { useEnvironments } from 'hooks/api/getters/useEnvironments/useEnvironments';
 | |
| import type { IEnvironment } from 'interfaces/environments';
 | |
| import { useEffect, useMemo } from 'react';
 | |
| import { type TimeSpanOption, timeSpanOptions } from '../useEventTimeline';
 | |
| import CloseIcon from '@mui/icons-material/Close';
 | |
| 
 | |
| const StyledCol = styled('div')(({ theme }) => ({
 | |
|     display: 'flex',
 | |
|     alignItems: 'center',
 | |
|     gap: theme.spacing(1),
 | |
| }));
 | |
| 
 | |
| const StyledFilter = styled(TextField)(({ theme }) => ({
 | |
|     '& > div': {
 | |
|         background: 'transparent',
 | |
|         color: theme.palette.text.secondary,
 | |
|         '& > .MuiSelect-select': {
 | |
|             padding: theme.spacing(0.5, 4, 0.5, 1),
 | |
|             background: 'transparent',
 | |
|         },
 | |
|         '& > fieldset': { borderColor: 'transparent' },
 | |
|     },
 | |
| }));
 | |
| 
 | |
| const StyledTimelineEventsCount = styled('span')(({ theme }) => ({
 | |
|     marginTop: theme.spacing(0.25),
 | |
| }));
 | |
| 
 | |
| interface IEventTimelineHeaderProps {
 | |
|     totalEvents: number;
 | |
|     timeSpan: TimeSpanOption;
 | |
|     setTimeSpan: (timeSpan: TimeSpanOption) => void;
 | |
|     environment: IEnvironment | undefined;
 | |
|     setEnvironment: (environment: IEnvironment) => void;
 | |
|     setOpen: (open: boolean) => void;
 | |
| }
 | |
| 
 | |
| export const EventTimelineHeader = ({
 | |
|     totalEvents,
 | |
|     timeSpan,
 | |
|     setTimeSpan,
 | |
|     environment,
 | |
|     setEnvironment,
 | |
|     setOpen,
 | |
| }: IEventTimelineHeaderProps) => {
 | |
|     const { environments } = useEnvironments();
 | |
| 
 | |
|     const activeEnvironments = useMemo(
 | |
|         () => environments.filter(({ enabled }) => enabled),
 | |
|         [environments],
 | |
|     );
 | |
| 
 | |
|     useEffect(() => {
 | |
|         if (activeEnvironments.length > 0 && !environment) {
 | |
|             const defaultEnvironment =
 | |
|                 activeEnvironments.find(({ type }) => type === 'production') ||
 | |
|                 activeEnvironments[0];
 | |
|             setEnvironment(defaultEnvironment);
 | |
|         }
 | |
|     }, [activeEnvironments]);
 | |
| 
 | |
|     return (
 | |
|         <>
 | |
|             <StyledCol>
 | |
|                 <StyledTimelineEventsCount>
 | |
|                     {totalEvents} event
 | |
|                     {totalEvents === 1 ? '' : 's'}
 | |
|                 </StyledTimelineEventsCount>
 | |
|                 <StyledFilter
 | |
|                     select
 | |
|                     size='small'
 | |
|                     variant='outlined'
 | |
|                     value={timeSpan.key}
 | |
|                     onChange={(e) =>
 | |
|                         setTimeSpan(
 | |
|                             timeSpanOptions.find(
 | |
|                                 ({ key }) => key === e.target.value,
 | |
|                             ) || timeSpanOptions[0],
 | |
|                         )
 | |
|                     }
 | |
|                 >
 | |
|                     {timeSpanOptions.map(({ key, label }) => (
 | |
|                         <MenuItem key={key} value={key}>
 | |
|                             {label}
 | |
|                         </MenuItem>
 | |
|                     ))}
 | |
|                 </StyledFilter>
 | |
|             </StyledCol>
 | |
|             <StyledCol>
 | |
|                 <ConditionallyRender
 | |
|                     condition={Boolean(environment)}
 | |
|                     show={() => (
 | |
|                         <StyledFilter
 | |
|                             select
 | |
|                             size='small'
 | |
|                             variant='outlined'
 | |
|                             value={environment!.name}
 | |
|                             onChange={(e) =>
 | |
|                                 setEnvironment(
 | |
|                                     environments.find(
 | |
|                                         ({ name }) => name === e.target.value,
 | |
|                                     ) || environments[0],
 | |
|                                 )
 | |
|                             }
 | |
|                         >
 | |
|                             {environments.map(({ name }) => (
 | |
|                                 <MenuItem key={name} value={name}>
 | |
|                                     {name}
 | |
|                                 </MenuItem>
 | |
|                             ))}
 | |
|                         </StyledFilter>
 | |
|                     )}
 | |
|                 />
 | |
|                 <Tooltip title='Hide timeline' arrow>
 | |
|                     <IconButton
 | |
|                         aria-label='close'
 | |
|                         size='small'
 | |
|                         onClick={() => setOpen(false)}
 | |
|                     >
 | |
|                         <CloseIcon />
 | |
|                     </IconButton>
 | |
|                 </Tooltip>
 | |
|             </StyledCol>
 | |
|         </>
 | |
|     );
 | |
| };
 |