Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Related to: https://linear.app/unleash/issue/2-511/exploration-build-data-for-the-possibility-of-showing-an-alert-to-the Namely: https://unleash-internal.slack.com/archives/C046LV85N3C/p1671443897386729 The idea is to have a general message banner that can be controlled through a feature flag in Unleash to display announcements, warnings, informations, etc. Currently using mock feature flags, but the idea is to bind this to a feature flag we can manage in our Unleash instance, and use its payload to provide information to end users whenever we want. Co-authored-by: Gastón Fournier <gaston@getunleash.ai>
- Loading branch information
Showing
6 changed files
with
150 additions
and
1 deletion.
There are no files selected for viewing
139 changes: 139 additions & 0 deletions
139
frontend/src/component/common/MessageBanner/MessageBanner.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import { WarningAmber } from '@mui/icons-material'; | ||
import { styled, Icon, Link } from '@mui/material'; | ||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||
|
||
const StyledBar = styled('aside', { | ||
shouldForwardProp: prop => prop !== 'variant', | ||
})<{ variant?: BannerVariant }>(({ theme, variant = 'neutral' }) => ({ | ||
position: 'relative', | ||
zIndex: 1, | ||
display: 'flex', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
padding: theme.spacing(1), | ||
gap: theme.spacing(1), | ||
borderBottom: '1px solid', | ||
borderColor: theme.palette[variant].border, | ||
background: theme.palette[variant].light, | ||
color: theme.palette[variant].dark, | ||
})); | ||
|
||
const StyledIcon = styled('div', { | ||
shouldForwardProp: prop => prop !== 'variant', | ||
})<{ variant?: BannerVariant }>(({ theme, variant = 'neutral' }) => ({ | ||
display: 'flex', | ||
alignItems: 'center', | ||
color: theme.palette[variant].main, | ||
})); | ||
|
||
const StyledMessage = styled('div')(({ theme }) => ({ | ||
fontSize: theme.fontSizes.smallBody, | ||
})); | ||
|
||
const StyledLink = styled(Link)(({ theme }) => ({ | ||
fontSize: theme.fontSizes.smallBody, | ||
})); | ||
|
||
type BannerVariant = 'warning' | 'info' | 'error' | 'success' | 'neutral'; | ||
|
||
interface IMessageFlag { | ||
enabled: boolean; | ||
message: string; | ||
variant?: BannerVariant; | ||
icon?: string; | ||
link?: string; | ||
linkText?: string; | ||
plausibleEvent?: string; | ||
} | ||
|
||
// TODO: Grab a real feature flag instead | ||
const mockFlag: IMessageFlag = { | ||
enabled: true, | ||
message: | ||
'<strong>Heads up!</strong> It seems like one of your client instances might be misbehaving.', | ||
variant: 'warning', | ||
link: '/admin/network', | ||
linkText: 'View Network', | ||
plausibleEvent: 'network_warning', | ||
}; | ||
|
||
export const MessageBanner = () => { | ||
const { uiConfig } = useUiConfig(); | ||
|
||
const { enabled, message, variant, icon, link, linkText, plausibleEvent } = | ||
{ ...mockFlag, enabled: uiConfig.flags.messageBanner }; | ||
|
||
if (!enabled) return null; | ||
|
||
return ( | ||
<StyledBar variant={variant}> | ||
<StyledIcon variant={variant}> | ||
<BannerIcon icon={icon} variant={variant} /> | ||
</StyledIcon> | ||
<StyledMessage dangerouslySetInnerHTML={{ __html: message }} /> | ||
<BannerButton | ||
link={link} | ||
linkText={linkText} | ||
plausibleEvent={plausibleEvent} | ||
/> | ||
</StyledBar> | ||
); | ||
}; | ||
|
||
interface IBannerIconProps { | ||
icon?: string; | ||
variant?: BannerVariant; | ||
} | ||
|
||
const BannerIcon = ({ icon, variant }: IBannerIconProps) => { | ||
if (icon === 'none') return null; | ||
if (icon) return <Icon>{icon}</Icon>; | ||
if (variant) return <WarningAmber />; | ||
// TODO: Add defaults for other variants? | ||
return null; | ||
}; | ||
|
||
interface IBannerButtonProps { | ||
link?: string; | ||
linkText?: string; | ||
plausibleEvent?: string; | ||
} | ||
|
||
const BannerButton = ({ | ||
link, | ||
linkText = 'More info', | ||
plausibleEvent, | ||
}: IBannerButtonProps) => { | ||
if (!link) return null; | ||
|
||
const navigate = useNavigate(); | ||
const tracker = usePlausibleTracker(); | ||
const external = link.startsWith('http'); | ||
|
||
const trackEvent = () => { | ||
if (!plausibleEvent) return; | ||
tracker.trackEvent('message_banner', { | ||
props: { event: plausibleEvent }, | ||
}); | ||
}; | ||
|
||
if (external) | ||
return ( | ||
<StyledLink href={link} target="_blank" onClick={trackEvent}> | ||
{linkText} | ||
</StyledLink> | ||
); | ||
else | ||
return ( | ||
<StyledLink | ||
onClick={() => { | ||
trackEvent(); | ||
navigate(link); | ||
}} | ||
> | ||
{linkText} | ||
</StyledLink> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters