diff --git a/frontend/src/assets/img/aiPreview.svg b/frontend/src/assets/img/aiPreview.svg
new file mode 100644
index 0000000000..5700cb8a78
--- /dev/null
+++ b/frontend/src/assets/img/aiPreview.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/component/ai/AIChat.tsx b/frontend/src/component/ai/AIChat.tsx
index 92b4042919..77656797ff 100644
--- a/frontend/src/component/ai/AIChat.tsx
+++ b/frontend/src/component/ai/AIChat.tsx
@@ -1,6 +1,6 @@
import { mutate } from 'swr';
import { ReactComponent as AIIcon } from 'assets/icons/AI.svg';
-import { IconButton, styled, useMediaQuery } from '@mui/material';
+import { IconButton, styled, Tooltip, useMediaQuery } from '@mui/material';
import { useEffect, useRef, useState } from 'react';
import useToast from 'hooks/useToast';
import { formatUnknownError } from 'utils/formatUnknownError';
@@ -198,19 +198,21 @@ export const AIChat = () => {
if (!open) {
return (
- {
- trackEvent('unleash-ai-chat', {
- props: {
- eventType: 'open',
- },
- });
- setOpen(true);
- }}
- >
-
-
+
+ {
+ trackEvent('unleash-ai-chat', {
+ props: {
+ eventType: 'open',
+ },
+ });
+ setOpen(true);
+ }}
+ >
+
+
+
);
}
diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash.tsx
index bfdb849f4c..a4341f4955 100644
--- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash.tsx
+++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleash.tsx
@@ -1,4 +1,3 @@
-import type { ReactNode } from 'react';
import { useUiFlag } from 'hooks/useUiFlag';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useLocalStorageState } from 'hooks/useLocalStorageState';
@@ -13,13 +12,18 @@ import {
} from '@mui/material';
import Signals from '@mui/icons-material/Sensors';
import type { NavigationMode } from 'component/layout/MainLayout/NavigationSidebar/NavigationMode';
-import { NewInUnleashItem } from './NewInUnleashItem';
+import {
+ NewInUnleashItem,
+ type NewInUnleashItemDetails,
+} from './NewInUnleashItem';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import { ReactComponent as SignalsPreview } from 'assets/img/signals.svg';
import LinearScaleIcon from '@mui/icons-material/LinearScale';
import { useNavigate } from 'react-router-dom';
import { useEventTimelineContext } from 'component/events/EventTimeline/EventTimelineContext';
import { ReactComponent as EventTimelinePreview } from 'assets/img/eventTimeline.svg';
+import { ReactComponent as AIIcon } from 'assets/icons/AI.svg';
+import { ReactComponent as AIPreview } from 'assets/img/aiPreview.svg';
const StyledNewInUnleash = styled('div')(({ theme }) => ({
margin: theme.spacing(2, 0, 1, 0),
@@ -75,17 +79,11 @@ const StyledLinearScaleIcon = styled(LinearScaleIcon)(({ theme }) => ({
color: theme.palette.primary.main,
}));
-type NewItem = {
- label: string;
- summary: string;
- icon: ReactNode;
- onCheckItOut: () => void;
- docsLink: string;
- show: boolean;
- longDescription: ReactNode;
- preview?: ReactNode;
- beta?: boolean;
-};
+const StyledAIIcon = styled(AIIcon)(({ theme }) => ({
+ '& > path': {
+ fill: theme.palette.primary.main,
+ },
+}));
interface INewInUnleashProps {
mode?: NavigationMode;
@@ -102,12 +100,17 @@ export const NewInUnleash = ({
'new-in-unleash-seen:v1',
new Set(),
);
- const { isOss, isEnterprise } = useUiConfig();
+ const {
+ isOss,
+ isEnterprise,
+ uiConfig: { unleashAIAvailable },
+ } = useUiConfig();
const signalsEnabled = useUiFlag('signals');
+ const unleashAIEnabled = useUiFlag('unleashAI');
const { setHighlighted } = useEventTimelineContext();
- const items: NewItem[] = [
+ const items: NewInUnleashItemDetails[] = [
{
label: 'Signals & Actions',
summary: 'Listen to signals via Webhooks',
@@ -174,6 +177,30 @@ export const NewInUnleash = ({
>
),
},
+ {
+ label: 'Unleash AI',
+ summary:
+ 'Enhance your Unleash experience with the help of the Unleash AI assistant',
+ icon: ,
+ preview: ,
+ show: Boolean(unleashAIAvailable) && unleashAIEnabled,
+ beta: true,
+ longDescription: (
+ <>
+
+ Meet the Unleash AI assistant, designed to make your
+ experience with Unleash easier and more intuitive,
+ whether you're handling tasks or looking for guidance.
+
+
+
+ Start chatting by using the button in the bottom right
+ corner of the page, and discover all the ways the
+ Unleash AI assistant can help you.
+
+ >
+ ),
+ },
];
const visibleItems = items.filter(
diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashItem.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashItem.tsx
index 743e0c3a05..7de61ab86a 100644
--- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashItem.tsx
+++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashItem.tsx
@@ -13,6 +13,18 @@ import { NewInUnleashTooltip } from './NewInUnleashTooltip';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { Badge } from 'component/common/Badge/Badge';
+export type NewInUnleashItemDetails = {
+ label: string;
+ summary: string;
+ icon: ReactNode;
+ onCheckItOut?: () => void;
+ docsLink?: string;
+ show: boolean;
+ longDescription: ReactNode;
+ preview?: ReactNode;
+ beta?: boolean;
+};
+
const StyledItemButton = styled(ListItemButton)(({ theme }) => ({
outline: `1px solid ${theme.palette.divider}`,
borderRadius: theme.shape.borderRadiusMedium,
@@ -32,22 +44,17 @@ const StyledItemTitle = styled('div')(({ theme }) => ({
display: 'flex',
gap: theme.spacing(1),
alignItems: 'center',
+ height: theme.spacing(3),
}));
const StyledItemButtonClose = styled(IconButton)(({ theme }) => ({
padding: theme.spacing(0.25),
}));
-interface INewInUnleashItemProps {
- icon: ReactNode;
+interface INewInUnleashItemProps
+ extends Omit {
onClick: () => void;
onDismiss: () => void;
- label: string;
- longDescription: ReactNode;
- onCheckItOut: () => void;
- docsLink: string;
- preview?: ReactNode;
- summary: string;
beta: boolean;
}
diff --git a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashTooltip.tsx b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashTooltip.tsx
index c2491ab9e3..9233ece2ce 100644
--- a/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashTooltip.tsx
+++ b/frontend/src/component/layout/MainLayout/NavigationSidebar/NewInUnleash/NewInUnleashTooltip.tsx
@@ -78,15 +78,20 @@ const StyledTitle = styled('div')(({ theme }) => ({
}));
const ReadMore = styled(Box)(({ theme }) => ({
- padding: theme.spacing(3, 0),
+ paddingTop: theme.spacing(3),
+ paddingBottom: theme.spacing(1),
+}));
+
+const StyledCheckItOutButton = styled(Button)(({ theme }) => ({
+ marginTop: theme.spacing(2),
}));
export const NewInUnleashTooltip: FC<{
children: React.ReactElement;
title: string;
longDescription: ReactNode;
- docsLink: string;
- onCheckItOut: () => void;
+ docsLink?: string;
+ onCheckItOut?: () => void;
open: boolean;
preview?: ReactNode;
onClose: () => void;
@@ -134,31 +139,41 @@ export const NewInUnleashTooltip: FC<{
/>
{longDescription}
-
-
- Read more in our
- documentation
-
-
- {
- event.stopPropagation();
- onClose();
- onCheckItOut();
- }}
- >
- Check it out
-
+
+
+ Read more in our
+ documentation
+
+
+ }
+ />
+ {
+ event.stopPropagation();
+ onClose();
+ onCheckItOut!();
+ }}
+ >
+ Check it out
+
+ }
+ />