mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: new in unleash tooltip (#7991)
This commit is contained in:
		
							parent
							
								
									742504793c
								
							
						
					
					
						commit
						c69036c5a9
					
				@ -105,7 +105,7 @@ const StageBox = styled(Box, {
 | 
			
		||||
const ColorFill = styled(Box)(({ theme }) => ({
 | 
			
		||||
    backgroundColor: theme.palette.primary.light,
 | 
			
		||||
    color: theme.palette.primary.contrastText,
 | 
			
		||||
    borderRadius: theme.spacing(0, 0, 1, 1), // has to match the parent tooltip container
 | 
			
		||||
    borderRadius: `0 0 ${theme.shape.borderRadiusMedium}px ${theme.shape.borderRadiusMedium}px`, // has to match the parent tooltip container
 | 
			
		||||
    margin: theme.spacing(-1, -1.5), // has to match the parent tooltip container
 | 
			
		||||
    padding: theme.spacing(2, 3),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,6 @@ import {
 | 
			
		||||
    styled,
 | 
			
		||||
} from '@mui/material';
 | 
			
		||||
import Signals from '@mui/icons-material/Sensors';
 | 
			
		||||
import { useNavigate } from 'react-router-dom';
 | 
			
		||||
import type { NavigationMode } from 'component/layout/MainLayout/NavigationSidebar/NavigationMode';
 | 
			
		||||
import { NewInUnleashItem } from './NewInUnleashItem';
 | 
			
		||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
 | 
			
		||||
@ -71,7 +70,9 @@ type NewItem = {
 | 
			
		||||
    label: string;
 | 
			
		||||
    icon: ReactNode;
 | 
			
		||||
    link: string;
 | 
			
		||||
    docsLink: string;
 | 
			
		||||
    show: boolean;
 | 
			
		||||
    longDescription: ReactNode;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface INewInUnleashProps {
 | 
			
		||||
@ -86,7 +87,6 @@ export const NewInUnleash = ({
 | 
			
		||||
    onMiniModeClick,
 | 
			
		||||
}: INewInUnleashProps) => {
 | 
			
		||||
    const { trackEvent } = usePlausibleTracker();
 | 
			
		||||
    const navigate = useNavigate();
 | 
			
		||||
    const [seenItems, setSeenItems] = useLocalStorageState(
 | 
			
		||||
        'new-in-unleash-seen:v1',
 | 
			
		||||
        new Set(),
 | 
			
		||||
@ -99,7 +99,35 @@ export const NewInUnleash = ({
 | 
			
		||||
            label: 'Signals & Actions',
 | 
			
		||||
            icon: <StyledSignalsIcon />,
 | 
			
		||||
            link: '/integrations/signals',
 | 
			
		||||
            docsLink: 'https://docs.getunleash.io/reference/signals',
 | 
			
		||||
            show: isEnterprise() && signalsEnabled,
 | 
			
		||||
            longDescription: (
 | 
			
		||||
                <>
 | 
			
		||||
                    <p>
 | 
			
		||||
                        It allows you to respond to events in your real-time
 | 
			
		||||
                        monitoring system by automating tasks such as disabling
 | 
			
		||||
                        a beta feature in response to an increase in errors or a
 | 
			
		||||
                        drop in conversion rates.
 | 
			
		||||
                    </p>
 | 
			
		||||
 | 
			
		||||
                    <p>
 | 
			
		||||
                        <ul>
 | 
			
		||||
                            <li>
 | 
			
		||||
                                <b>Signal endpoints</b> are used to send signals
 | 
			
		||||
                                to Unleash. This allows you to integrate Unleash
 | 
			
		||||
                                with any external tool.
 | 
			
		||||
                            </li>
 | 
			
		||||
 | 
			
		||||
                            <li>
 | 
			
		||||
                                <b>Actions</b>, which are configured inside
 | 
			
		||||
                                projects, allow you to react to those signals
 | 
			
		||||
                                and enable or disable flags based on certain
 | 
			
		||||
                                conditions.
 | 
			
		||||
                            </li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                    </p>
 | 
			
		||||
                </>
 | 
			
		||||
            ),
 | 
			
		||||
        },
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
@ -135,18 +163,15 @@ export const NewInUnleash = ({
 | 
			
		||||
                New in Unleash
 | 
			
		||||
            </StyledNewInUnleashHeader>
 | 
			
		||||
            <StyledNewInUnleashList>
 | 
			
		||||
                {visibleItems.map(({ label, icon, link }) => (
 | 
			
		||||
                {visibleItems.map(
 | 
			
		||||
                    ({ label, icon, link, longDescription, docsLink }) => (
 | 
			
		||||
                        <NewInUnleashItem
 | 
			
		||||
                        key={label}
 | 
			
		||||
                        icon={icon}
 | 
			
		||||
                            onClick={() => {
 | 
			
		||||
                                trackEvent('new-in-unleash-click', {
 | 
			
		||||
                                    props: {
 | 
			
		||||
                                        label,
 | 
			
		||||
                                    },
 | 
			
		||||
                                });
 | 
			
		||||
                            navigate(link);
 | 
			
		||||
                            onItemClick?.();
 | 
			
		||||
                            }}
 | 
			
		||||
                            onDismiss={() => {
 | 
			
		||||
                                trackEvent('new-in-unleash-dismiss', {
 | 
			
		||||
@ -156,10 +181,14 @@ export const NewInUnleash = ({
 | 
			
		||||
                                });
 | 
			
		||||
                                setSeenItems(new Set([...seenItems, label]));
 | 
			
		||||
                            }}
 | 
			
		||||
                    >
 | 
			
		||||
                        {label}
 | 
			
		||||
                    </NewInUnleashItem>
 | 
			
		||||
                ))}
 | 
			
		||||
                            label={label}
 | 
			
		||||
                            icon={icon}
 | 
			
		||||
                            link={link}
 | 
			
		||||
                            longDescription={longDescription}
 | 
			
		||||
                            docsLink={docsLink}
 | 
			
		||||
                        />
 | 
			
		||||
                    ),
 | 
			
		||||
                )}
 | 
			
		||||
            </StyledNewInUnleashList>
 | 
			
		||||
        </StyledNewInUnleash>
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,14 @@
 | 
			
		||||
import type { ReactNode } from 'react';
 | 
			
		||||
import type * as React from 'react';
 | 
			
		||||
import { type ReactNode, useState } from 'react';
 | 
			
		||||
import {
 | 
			
		||||
    IconButton,
 | 
			
		||||
    ListItem,
 | 
			
		||||
    ListItemButton,
 | 
			
		||||
    Tooltip,
 | 
			
		||||
    styled,
 | 
			
		||||
    Tooltip,
 | 
			
		||||
} from '@mui/material';
 | 
			
		||||
import Close from '@mui/icons-material/Close';
 | 
			
		||||
import { NewInUnleashTooltip } from './NewInUnleashTooltip';
 | 
			
		||||
 | 
			
		||||
const StyledItemButton = styled(ListItemButton)(({ theme }) => ({
 | 
			
		||||
    justifyContent: 'space-between',
 | 
			
		||||
@ -30,26 +32,62 @@ interface INewInUnleashItemProps {
 | 
			
		||||
    icon: ReactNode;
 | 
			
		||||
    onClick: () => void;
 | 
			
		||||
    onDismiss: () => void;
 | 
			
		||||
    children: ReactNode;
 | 
			
		||||
    label: string;
 | 
			
		||||
    longDescription: ReactNode;
 | 
			
		||||
    link: string;
 | 
			
		||||
    docsLink: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const useTooltip = () => {
 | 
			
		||||
    const [open, setOpen] = useState(false);
 | 
			
		||||
 | 
			
		||||
    const handleTooltipClose = () => {
 | 
			
		||||
        setOpen(false);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const handleTooltipOpen = () => {
 | 
			
		||||
        setOpen(true);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return { open, handleTooltipOpen, handleTooltipClose };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const NewInUnleashItem = ({
 | 
			
		||||
    icon,
 | 
			
		||||
    onClick,
 | 
			
		||||
    onDismiss,
 | 
			
		||||
    children,
 | 
			
		||||
    label,
 | 
			
		||||
    longDescription,
 | 
			
		||||
    link,
 | 
			
		||||
    docsLink,
 | 
			
		||||
}: INewInUnleashItemProps) => {
 | 
			
		||||
    const { open, handleTooltipOpen, handleTooltipClose } = useTooltip();
 | 
			
		||||
 | 
			
		||||
    const onDismissClick = (e: React.MouseEvent) => {
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
        onDismiss();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <ListItem disablePadding onClick={onClick}>
 | 
			
		||||
        <ListItem
 | 
			
		||||
            disablePadding
 | 
			
		||||
            onClick={() => {
 | 
			
		||||
                onClick();
 | 
			
		||||
                handleTooltipOpen();
 | 
			
		||||
            }}
 | 
			
		||||
        >
 | 
			
		||||
            <NewInUnleashTooltip
 | 
			
		||||
                open={open}
 | 
			
		||||
                onClose={handleTooltipClose}
 | 
			
		||||
                title={label}
 | 
			
		||||
                longDescription={longDescription}
 | 
			
		||||
                link={link}
 | 
			
		||||
                docsLink={docsLink}
 | 
			
		||||
            >
 | 
			
		||||
                <StyledItemButton>
 | 
			
		||||
                    <StyledItemButtonContent>
 | 
			
		||||
                        {icon}
 | 
			
		||||
                    {children}
 | 
			
		||||
                        {label}
 | 
			
		||||
                    </StyledItemButtonContent>
 | 
			
		||||
                    <Tooltip title='Dismiss' arrow>
 | 
			
		||||
                        <StyledItemButtonClose
 | 
			
		||||
@ -61,6 +99,7 @@ export const NewInUnleashItem = ({
 | 
			
		||||
                        </StyledItemButtonClose>
 | 
			
		||||
                    </Tooltip>
 | 
			
		||||
                </StyledItemButton>
 | 
			
		||||
            </NewInUnleashTooltip>
 | 
			
		||||
        </ListItem>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,129 @@
 | 
			
		||||
import type * as React from 'react';
 | 
			
		||||
import type { FC, ReactNode } from 'react';
 | 
			
		||||
import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip';
 | 
			
		||||
import {
 | 
			
		||||
    Box,
 | 
			
		||||
    Button,
 | 
			
		||||
    Link,
 | 
			
		||||
    styled,
 | 
			
		||||
    Typography,
 | 
			
		||||
    ClickAwayListener,
 | 
			
		||||
} from '@mui/material';
 | 
			
		||||
import { type Link as RouterLink, useNavigate } from 'react-router-dom';
 | 
			
		||||
import OpenInNew from '@mui/icons-material/OpenInNew';
 | 
			
		||||
import { ReactComponent as UnleashLogo } from 'assets/img/logoWithWhiteText.svg';
 | 
			
		||||
 | 
			
		||||
const Header = styled(Box)(({ theme }) => ({
 | 
			
		||||
    backgroundColor: theme.palette.primary.light,
 | 
			
		||||
    color: theme.palette.primary.contrastText,
 | 
			
		||||
    borderRadius: `${theme.shape.borderRadiusMedium}px ${theme.shape.borderRadiusMedium}px 0 0`, // has to match the parent tooltip container
 | 
			
		||||
    margin: theme.spacing(-1, -1.5), // has to match the parent tooltip container
 | 
			
		||||
    padding: theme.spacing(2, 3),
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    justifyContent: 'center',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
    minHeight: '120px',
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const Body = styled(Box)(({ theme }) => ({
 | 
			
		||||
    padding: theme.spacing(2),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const StyledLink = styled(Link<typeof RouterLink | 'a'>)(({ theme }) => ({
 | 
			
		||||
    display: 'flex',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
    gap: theme.spacing(1),
 | 
			
		||||
    padding: 0,
 | 
			
		||||
    color: theme.palette.links,
 | 
			
		||||
    fontWeight: theme.fontWeight.medium,
 | 
			
		||||
    '&:hover, &:focus': {
 | 
			
		||||
        textDecoration: 'underline',
 | 
			
		||||
    },
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const StyledOpenInNew = styled(OpenInNew)(({ theme }) => ({
 | 
			
		||||
    fontSize: theme.spacing(2.25),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const StyledUnleashLogo = styled(UnleashLogo)({ width: '150px' });
 | 
			
		||||
 | 
			
		||||
const LongDescription = styled(Box)(({ theme }) => ({
 | 
			
		||||
    ul: {
 | 
			
		||||
        paddingLeft: theme.spacing(2),
 | 
			
		||||
    },
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const Title = styled(Typography)(({ theme }) => ({
 | 
			
		||||
    margin: theme.spacing(2, 0),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const ReadMore = styled(Box)(({ theme }) => ({
 | 
			
		||||
    margin: theme.spacing(3, 0),
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
export const NewInUnleashTooltip: FC<{
 | 
			
		||||
    children: React.ReactElement<any, any>;
 | 
			
		||||
    title: string;
 | 
			
		||||
    longDescription: ReactNode;
 | 
			
		||||
    docsLink: string;
 | 
			
		||||
    link: string;
 | 
			
		||||
    open: boolean;
 | 
			
		||||
    onClose: () => void;
 | 
			
		||||
}> = ({ children, title, longDescription, link, docsLink, open, onClose }) => {
 | 
			
		||||
    const navigate = useNavigate();
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <HtmlTooltip
 | 
			
		||||
            disableFocusListener
 | 
			
		||||
            disableHoverListener
 | 
			
		||||
            disableTouchListener
 | 
			
		||||
            onClose={onClose}
 | 
			
		||||
            open={open}
 | 
			
		||||
            maxHeight={800}
 | 
			
		||||
            maxWidth={350}
 | 
			
		||||
            arrow
 | 
			
		||||
            tabIndex={0}
 | 
			
		||||
            placement='right-end'
 | 
			
		||||
            title={
 | 
			
		||||
                <ClickAwayListener onClickAway={onClose}>
 | 
			
		||||
                    <Box>
 | 
			
		||||
                        <Header>
 | 
			
		||||
                            <StyledUnleashLogo />
 | 
			
		||||
                        </Header>
 | 
			
		||||
                        <Body>
 | 
			
		||||
                            <Title>{title}</Title>
 | 
			
		||||
                            <LongDescription>{longDescription}</LongDescription>
 | 
			
		||||
                            <ReadMore>
 | 
			
		||||
                                <StyledLink
 | 
			
		||||
                                    component='a'
 | 
			
		||||
                                    href={docsLink}
 | 
			
		||||
                                    underline='hover'
 | 
			
		||||
                                    rel='noopener noreferrer'
 | 
			
		||||
                                    target='_blank'
 | 
			
		||||
                                >
 | 
			
		||||
                                    <StyledOpenInNew /> Read more in our
 | 
			
		||||
                                    documentation
 | 
			
		||||
                                </StyledLink>
 | 
			
		||||
                            </ReadMore>
 | 
			
		||||
                            <Button
 | 
			
		||||
                                variant='contained'
 | 
			
		||||
                                color='primary'
 | 
			
		||||
                                type='submit'
 | 
			
		||||
                                size='small'
 | 
			
		||||
                                onClick={(event) => {
 | 
			
		||||
                                    event.stopPropagation();
 | 
			
		||||
                                    onClose();
 | 
			
		||||
                                    navigate(link);
 | 
			
		||||
                                }}
 | 
			
		||||
                            >
 | 
			
		||||
                                Check it out
 | 
			
		||||
                            </Button>
 | 
			
		||||
                        </Body>
 | 
			
		||||
                    </Box>
 | 
			
		||||
                </ClickAwayListener>
 | 
			
		||||
            }
 | 
			
		||||
        >
 | 
			
		||||
            {children}
 | 
			
		||||
        </HtmlTooltip>
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user