Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add Unleash AI to New in Unleash #8642

Merged
merged 2 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions frontend/src/assets/img/aiPreview.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 16 additions & 14 deletions frontend/src/component/ai/AIChat.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -198,19 +198,21 @@ export const AIChat = () => {
if (!open) {
return (
<StyledAIIconContainer demoStepsVisible={demoStepsVisible}>
<StyledAIIconButton
size='large'
onClick={() => {
trackEvent('unleash-ai-chat', {
props: {
eventType: 'open',
},
});
setOpen(true);
}}
>
<AIIcon />
</StyledAIIconButton>
<Tooltip arrow title='Unleash AI'>
<StyledAIIconButton
size='large'
onClick={() => {
trackEvent('unleash-ai-chat', {
props: {
eventType: 'open',
},
});
setOpen(true);
}}
>
<AIIcon />
</StyledAIIconButton>
</Tooltip>
</StyledAIIconContainer>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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),
Expand Down Expand Up @@ -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;
Expand All @@ -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',
Expand Down Expand Up @@ -174,6 +177,30 @@ export const NewInUnleash = ({
</>
),
},
{
label: 'Unleash AI',
summary:
'Enhance your Unleash experience with the help of the Unleash AI assistant',
icon: <StyledAIIcon />,
preview: <AIPreview />,
show: Boolean(unleashAIAvailable) && unleashAIEnabled,
beta: true,
longDescription: (
<>
<p>
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.
</p>

<p>
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.
</p>
</>
),
},
];

const visibleItems = items.filter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<NewInUnleashItemDetails, 'show' | 'beta'> {
onClick: () => void;
onDismiss: () => void;
label: string;
longDescription: ReactNode;
onCheckItOut: () => void;
docsLink: string;
preview?: ReactNode;
summary: string;
beta: boolean;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<any, any>;
title: string;
longDescription: ReactNode;
docsLink: string;
onCheckItOut: () => void;
docsLink?: string;
onCheckItOut?: () => void;
open: boolean;
preview?: ReactNode;
onClose: () => void;
Expand Down Expand Up @@ -134,31 +139,41 @@ export const NewInUnleashTooltip: FC<{
/>
</StyledTitle>
<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();
onCheckItOut();
}}
>
Check it out
</Button>
<ConditionallyRender
condition={Boolean(docsLink)}
show={
<ReadMore>
<StyledLink
component='a'
href={docsLink}
underline='hover'
rel='noopener noreferrer'
target='_blank'
>
<StyledOpenInNew /> Read more in our
documentation
</StyledLink>
</ReadMore>
}
/>
<ConditionallyRender
condition={Boolean(onCheckItOut)}
show={
<StyledCheckItOutButton
variant='contained'
color='primary'
type='submit'
size='small'
onClick={(event) => {
event.stopPropagation();
onClose();
onCheckItOut!();
}}
>
Check it out
</StyledCheckItOutButton>
}
/>
</Body>
</Box>
</ClickAwayListener>
Expand Down
Loading