Compare commits

...

2 Commits

Author SHA1 Message Date
Ryan Laurie
4ca671d873 frontend notifications center 2026-03-27 11:11:32 -06:00
Ryan Laurie
c7be61bf41 frontend notifications center 2026-03-27 11:11:17 -06:00
2 changed files with 88 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ import { Nav as DetailViewNav } from "metabase/detail-view/components";
import { DETAIL_VIEW_PADDING_LEFT } from "metabase/detail-view/constants";
import { MetabotAppBarButton } from "metabase/metabot/components/MetabotAppBarButton";
import { useMetabotEnabledEmbeddingAware } from "metabase/metabot/hooks";
import { NotificationArea } from "metabase/notifications/AppNotifications/NotificationArea";
import { PLUGIN_REMOTE_SYNC } from "metabase/plugins";
import { Box, Flex } from "metabase/ui";
import type { CollectionId } from "metabase-types/api";
@@ -113,6 +114,7 @@ const AppBarLarge = ({
(isEmbeddingIframe ? <SearchBar /> : <SearchButton mr="md" />)}
{isNewButtonVisible && <NewItemButton collectionId={collectionId} />}
{<MetabotAppBarButton />}
<NotificationArea />
{isAppSwitcherVisible && (
<Box c="text-primary" aria-label={t`Settings menu`}>
<AppSwitcher />

View File

@@ -0,0 +1,86 @@
import { Indicator, Notification } from "@mantine/core";
import { t } from "ttag";
import { Button, Flex, Icon, type IconName, Popover, Stack, Text } from "metabase/ui";
import type { ColorName } from "metabase/ui/colors";
import { IconButton } from "metabase/visualizations/components/settings/ChartSettingIconRadio.styled";
type NotificationContent = {
title: string;
body: string;
color?: ColorName;
actionButtonLabel?: string;
}
const testData: NotificationContent[] = [
{
title: "New version available",
body: "Metabase v60 is now available. Please update to the latest version to enjoy new features and improvements.",
color: "brand",
actionButtonLabel: "Update",
},
{
title: "Security update",
body: "Metabase v60.1 contains an important security update for Redshift impersonation. Please update as soon as possible.",
color: "warning",
actionButtonLabel: "Update",
},
{
title: "Bring your own model to Metabot",
body: "Visit the admin settings to configure AI assistance on this instance",
color: "success",
actionButtonLabel: "Configure",
},
]
export const NotificationArea = (): JSX.Element => {
return (
<Popover position="bottom-end">
<Popover.Target>
<Indicator>
<IconButton
data-testid="metabase-notifications"
icon="bell"
/>
</Indicator>
</Popover.Target>
<Popover.Dropdown bg="background-secondary">
<Stack gap="sm" p="md" mah="60rem">
{testData.map((notification, index) => (
<NotificationItem key={index} {...notification} />
))}
</Stack>
<Button variant="subtle" fullWidth mb="sm">
{t`Show all`}
</Button>
</Popover.Dropdown>
</Popover>
);
}
export const NotificationItem = ({ title, body, actionButtonLabel }: NotificationContent) => {
return (
<Notification
title={<Text fw="bold" fz="lg" mt="sm">{title}</Text>}
maw="20rem"
m="0"
color={"none"}
withBorder
bd="1px solid var(--mb-color-border)"
style={{ boxShadow: "none" }}
>
<Text lh="md" py="sm">
{body}
</Text>
<Flex gap="sm" justify="flex-end" mb="sm">
<Button variant="subtle" size="xs" mt="sm">
{t`Dismiss`}
</Button>
<Button variant="light" size="xs" mt="sm">
{actionButtonLabel}
</Button>
</Flex>
</Notification>
);
}