From 4e2158ab641971b827dbe15886ee925ff9ba4280 Mon Sep 17 00:00:00 2001 From: Delirium Date: Tue, 27 May 2025 17:46:44 +0200 Subject: [PATCH] new Kai design (#3443) * redesign is inevitable * ui: change kai design, add sessions to list, swap to new icon * ui: some changes for suggestions in thread --- frontend/app/components/Kai/KaiChat.tsx | 84 ++++++++----- frontend/app/components/Kai/KaiService.ts | 5 +- frontend/app/components/Kai/KaiStore.ts | 11 +- frontend/app/components/Kai/SocketManager.ts | 8 +- .../components/Kai/components/ChatHeader.tsx | 82 +++++++------ .../components/Kai/components/ChatInput.tsx | 111 +++++++++++++----- .../app/components/Kai/components/ChatLog.tsx | 25 ++-- .../app/components/Kai/components/ChatMsg.tsx | 67 +++++------ .../components/Kai/components/ChatsModal.tsx | 7 +- .../app/components/Kai/components/Ideas.tsx | 77 +++++++----- .../Kai/components/IntroSection.tsx | 32 +++-- frontend/app/components/Modal/index.tsx | 2 + .../shared/SessionItem/SessionItem.tsx | 10 +- frontend/app/components/ui/Icons/index.ts | 1 + frontend/app/components/ui/Icons/kai_mono.tsx | 18 +++ frontend/app/components/ui/SVG.tsx | 6 +- frontend/app/svg/icons/kai-mono.svg | 11 ++ 17 files changed, 365 insertions(+), 192 deletions(-) create mode 100644 frontend/app/components/ui/Icons/kai_mono.tsx create mode 100644 frontend/app/svg/icons/kai-mono.svg diff --git a/frontend/app/components/Kai/KaiChat.tsx b/frontend/app/components/Kai/KaiChat.tsx index d3952cffa..4d3d13586 100644 --- a/frontend/app/components/Kai/KaiChat.tsx +++ b/frontend/app/components/Kai/KaiChat.tsx @@ -18,7 +18,7 @@ function KaiChat() { const chatTitle = kaiStore.chatTitle; const setTitle = kaiStore.setTitle; const userId = userStore.account.id; - const userLetter = userStore.account.name[0].toUpperCase(); + const userName = userStore.account.name; const { activeSiteId } = projectsStore; const [section, setSection] = React.useState<'intro' | 'chat'>('intro'); const [threadId, setThreadId] = React.useState(null); @@ -44,7 +44,11 @@ function KaiChat() { hideModal(); }} />, - { right: true, width: 300 }, + { + right: true, + width: 320, + className: 'bg-none flex items-center h-screen', + }, ); }; @@ -93,44 +97,70 @@ function KaiChat() { const newThread = await kaiService.createKaiChat(activeSiteId); if (newThread) { setThreadId(newThread.toString()); + kaiStore.setTitle(null); setSection('chat'); } else { toast.error("Something wen't wrong. Please try again later."); } }; + + const onCancel = () => { + if (!threadId) return; + void kaiStore.cancelGeneration({ + projectId: activeSiteId, + threadId, + }); + }; + return ( -
+
-
- {section === 'intro' ? ( - - ) : ( - - )} -
+ {section === 'intro' ? ( + <> +
+ +
+
+ OpenReplay AI can make mistakes. Verify its outputs. +
+ + ) : ( + + )}
); diff --git a/frontend/app/components/Kai/KaiService.ts b/frontend/app/components/Kai/KaiService.ts index 48ab8eafc..22cade0f8 100644 --- a/frontend/app/components/Kai/KaiService.ts +++ b/frontend/app/components/Kai/KaiService.ts @@ -36,6 +36,7 @@ export default class KaiService extends AiService { supports_visualization: boolean; chart: string; chart_data: string; + sessions?: Record[]; }[]; title: string; }> => { @@ -128,7 +129,9 @@ export default class KaiService extends AiService { projectId: string, threadId?: string | null, ): Promise => { - const endpoint = (threadId) ? `/kai/${projectId}/chats/${threadId}/prompt-suggestions` : `/kai/${projectId}/prompt-suggestions`; + const endpoint = threadId + ? `/kai/${projectId}/chats/${threadId}/prompt-suggestions` + : `/kai/${projectId}/prompt-suggestions`; const r = await this.client.get(endpoint); if (!r.ok) { throw new Error('Failed to fetch prompt suggestions'); diff --git a/frontend/app/components/Kai/KaiStore.ts b/frontend/app/components/Kai/KaiStore.ts index 7369b25b9..e7f496176 100644 --- a/frontend/app/components/Kai/KaiStore.ts +++ b/frontend/app/components/Kai/KaiStore.ts @@ -3,6 +3,7 @@ import { BotChunk, ChatManager } from './SocketManager'; import { kaiService as aiService, kaiService } from 'App/services'; import { toast } from 'react-toastify'; import Widget from 'App/mstore/types/widget'; +import Session, { ISession } from '@/types/session/session'; export interface Message { text: string; @@ -15,6 +16,7 @@ export interface Message { supports_visualization: boolean; feedback: boolean | null; duration: number; + sessions?: Session[]; } export interface SentMessage extends Omit< @@ -161,6 +163,9 @@ class KaiStore { chart: m.chart, supports_visualization: m.supports_visualization, chart_data: m.chart_data, + sessions: m.sessions + ? m.sessions.map((s) => new Session(s)) + : undefined, }; }), ); @@ -220,6 +225,9 @@ class KaiStore { chart: '', supports_visualization: msg.supports_visualization, chart_data: '', + sessions: msg.sessions + ? msg.sessions.map((s) => new Session(s)) + : undefined, }; this.bumpUsage(); this.addMessage(msgObj); @@ -268,7 +276,7 @@ class KaiStore { deleting.push(this.lastKaiMessage.index); } this.deleteAtIndex(deleting); - this.setReplacing(false); + this.setReplacing(null); } this.addMessage({ text: message, @@ -309,7 +317,6 @@ class KaiStore { cancelGeneration = async (settings: { projectId: string; - userId: string; threadId: string; }) => { try { diff --git a/frontend/app/components/Kai/SocketManager.ts b/frontend/app/components/Kai/SocketManager.ts index 7fcda3171..5906890c3 100644 --- a/frontend/app/components/Kai/SocketManager.ts +++ b/frontend/app/components/Kai/SocketManager.ts @@ -1,5 +1,6 @@ import io from 'socket.io-client'; import { toast } from 'react-toastify'; +import { ISession } from '@/types/session/session'; export class ChatManager { socket: ReturnType; @@ -77,9 +78,7 @@ export class ChatManager { msgCallback, titleCallback, }: { - msgCallback: ( - msg: StateEvent | BotChunk, - ) => void; + msgCallback: (msg: StateEvent | BotChunk) => void; titleCallback: (title: string) => void; }) => { this.socket.on('chunk', (msg: BotChunk) => { @@ -111,7 +110,8 @@ export interface BotChunk { messageId: string; duration: number; supports_visualization: boolean; - type: 'chunk' + sessions?: ISession[]; + type: 'chunk'; } interface StateEvent { diff --git a/frontend/app/components/Kai/components/ChatHeader.tsx b/frontend/app/components/Kai/components/ChatHeader.tsx index ae3cb4068..29aaa4365 100644 --- a/frontend/app/components/Kai/components/ChatHeader.tsx +++ b/frontend/app/components/Kai/components/ChatHeader.tsx @@ -1,56 +1,68 @@ import React from 'react'; import { Icon } from 'UI'; -import { MessagesSquare, ArrowLeft } from 'lucide-react'; +import { MessagesSquare, ArrowLeft, SquarePen } from 'lucide-react'; import { useTranslation } from 'react-i18next'; function ChatHeader({ openChats = () => {}, goBack, chatTitle, + onCreate, }: { goBack?: () => void; openChats?: () => void; chatTitle: string | null; + onCreate: () => void; }) { const { t } = useTranslation(); + //absolute top-0 left-0 right-0 z-10 return ( -
-
- {goBack ? ( +
+
+
+ {goBack ? ( +
+ +
{t('Back')}
+
+ ) : ( +
+ +
Kai
+
+ )} +
+
+ {chatTitle ? ( +
+ {chatTitle} +
+ ) : null} +
+
+ {goBack ? ( +
+ +
{t('New Chat')}
+
+ ) : null}
- -
{t('Back')}
+ +
{t('Chats')}
- ) : null} -
-
- {chatTitle ? ( -
- {chatTitle} -
- ) : ( - <> - -
Kai
- - )} -
-
-
- -
{t('Chats')}
diff --git a/frontend/app/components/Kai/components/ChatInput.tsx b/frontend/app/components/Kai/components/ChatInput.tsx index 237b79d6c..b860c4c32 100644 --- a/frontend/app/components/Kai/components/ChatInput.tsx +++ b/frontend/app/components/Kai/components/ChatInput.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Button, Input, Tooltip } from 'antd'; -import { SendHorizonal, OctagonX } from 'lucide-react'; +import { X, ArrowUp } from 'lucide-react'; import { kaiStore } from '../KaiStore'; import { observer } from 'mobx-react-lite'; import Usage from './Usage'; @@ -8,11 +8,13 @@ import Usage from './Usage'; function ChatInput({ isLoading, onSubmit, - threadId, + isArea, + onCancel, }: { isLoading?: boolean; onSubmit: (str: string) => void; - threadId: string; + onCancel: () => void; + isArea?: boolean; }) { const inputRef = React.useRef(null); const usage = kaiStore.usage; @@ -28,8 +30,7 @@ function ChatInput({ return; } if (isProcessing) { - const settings = { projectId: '2325', userId: '0', threadId }; - void kaiStore.cancelGeneration(settings); + onCancel(); } else { if (inputValue.length > 0) { onSubmit(inputValue); @@ -50,7 +51,34 @@ function ChatInput({ }, [inputValue]); const isReplacing = kaiStore.replacing !== null; - + const placeholder = limited + ? `You've reached the daily limit for queries, come again tomorrow!` + : 'Ask anything about your product and users...'; + if (isArea) { + return ( +
+ setInputValue(e.target.value)} + /> +
+ +
+
+ ); + } return (
setInputValue(e.target.value)} @@ -76,31 +101,19 @@ function ChatInput({ + + ); +} + export default observer(ChatInput); diff --git a/frontend/app/components/Kai/components/ChatLog.tsx b/frontend/app/components/Kai/components/ChatLog.tsx index 5c3dca6c5..d06e9df4b 100644 --- a/frontend/app/components/Kai/components/ChatLog.tsx +++ b/frontend/app/components/Kai/components/ChatLog.tsx @@ -1,7 +1,7 @@ import React from 'react'; import ChatInput from './ChatInput'; import ChatMsg, { ChatNotice } from './ChatMsg'; -import Ideas from "./Ideas"; +import Ideas from './Ideas'; import { Loader } from 'UI'; import { kaiStore } from '../KaiStore'; import { observer } from 'mobx-react-lite'; @@ -9,17 +9,17 @@ import { observer } from 'mobx-react-lite'; function ChatLog({ projectId, threadId, - userLetter, initialMsg, chatTitle, setInitialMsg, + onCancel, }: { projectId: string; threadId: any; - userLetter: string; initialMsg: string | null; setInitialMsg: (msg: string | null) => void; chatTitle: string | null; + onCancel: () => void; }) { const messages = kaiStore.messages; const loading = kaiStore.loadingChat; @@ -51,11 +51,15 @@ function ChatLog({ }); }, [messages.length, processingStage]); - const lastHumanMsgInd: null | number = kaiStore.lastHumanMessage.index; + const lastKaiMessageInd: null | number = kaiStore.lastKaiMessage.index; + const lastHumanMsgInd: number | null = kaiStore.lastHumanMessage.index; + const showIdeas = + !processingStage && lastKaiMessageInd === messages.length - 1; return (
( ) : null} - {(!processingStage && lastHumanMsgInd && messages.length == lastHumanMsgInd + 2) ? onSubmit(query)} projectId={projectId} threadId={threadId}/> : null} + {showIdeas ? ( + onSubmit(query)} + projectId={projectId} + threadId={threadId} + /> + ) : null}
-
- +
+
diff --git a/frontend/app/components/Kai/components/ChatMsg.tsx b/frontend/app/components/Kai/components/ChatMsg.tsx index d335952ae..5239f9745 100644 --- a/frontend/app/components/Kai/components/ChatMsg.tsx +++ b/frontend/app/components/Kai/components/ChatMsg.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Icon, CopyButton } from 'UI'; +import { CopyButton } from 'UI'; import { observer } from 'mobx-react-lite'; import cn from 'classnames'; import Markdown from 'react-markdown'; @@ -8,7 +8,7 @@ import { Loader, ThumbsUp, ThumbsDown, - ListRestart, + SquarePen, FileDown, Clock, ChartLine, @@ -20,6 +20,7 @@ import { durationFormatted } from 'App/date'; import WidgetChart from '@/components/Dashboard/components/WidgetChart'; import Widget from 'App/mstore/types/widget'; import { useTranslation } from 'react-i18next'; +import SessionItem from 'Shared/SessionItem'; function ChatMsg({ userName, @@ -168,28 +169,12 @@ function ChatMsg({ }, [metricData, chart_data]); return (
- {isUser ? ( -
- {userName} -
- ) : ( -
- -
- )} -
+
) : null} + {message.sessions ? ( +
+ {message.sessions.map((session) => ( +
+ +
+ ))} +
+ ) : null} {isUser ? ( - <> -
- -
{t('Edit')}
-
+
+ +
+ +
+
{t('Cancel')}
- +
) : (
{duration ? : null} diff --git a/frontend/app/components/Kai/components/ChatsModal.tsx b/frontend/app/components/Kai/components/ChatsModal.tsx index 16f374d15..8fb279aea 100644 --- a/frontend/app/components/Kai/components/ChatsModal.tsx +++ b/frontend/app/components/Kai/components/ChatsModal.tsx @@ -44,10 +44,13 @@ function ChatsModal({ refetch(); }; return ( -
+
- {t('Chats')} + {t('Previous Chats')}
{usage.percent > 80 ? (
diff --git a/frontend/app/components/Kai/components/Ideas.tsx b/frontend/app/components/Kai/components/Ideas.tsx index f1104756e..bade87acb 100644 --- a/frontend/app/components/Kai/components/Ideas.tsx +++ b/frontend/app/components/Kai/components/Ideas.tsx @@ -4,54 +4,69 @@ import { useQuery } from '@tanstack/react-query'; import { kaiService } from 'App/services'; import { useTranslation } from 'react-i18next'; -function Ideas({ onClick, projectId, threadId = null }: { onClick: (query: string) => void, projectId: string, threadId?: string | null }) { +function Ideas({ + onClick, + projectId, + threadId = null, +}: { + onClick: (query: string) => void; + projectId: string; + threadId?: string | null; +}) { const { t } = useTranslation(); - const { - data: suggestedPromptIdeas = [], - isPending, - } = useQuery({ - queryKey: ['kai', projectId, 'chats', threadId, 'prompt-suggestions'], - queryFn: () => kaiService.getPromptSuggestions(projectId, threadId), - staleTime: 1000 * 60, + const { data: suggestedPromptIdeas = [], isPending } = useQuery({ + queryKey: ['kai', projectId, 'chats', threadId, 'prompt-suggestions'], + queryFn: () => kaiService.getPromptSuggestions(projectId, threadId), + staleTime: 1000 * 60, }); const ideas = React.useMemo(() => { - const defaultPromptIdeas = [ - 'Top user journeys', - 'Where do users drop off', - 'Failed network requests today', - ]; - const result = suggestedPromptIdeas; - const targetSize = 3; - while (result.length < targetSize && defaultPromptIdeas.length) { - result.push(defaultPromptIdeas.pop()) - } + const defaultPromptIdeas = [ + 'Top user journeys', + 'Where do users drop off', + 'Failed network requests today', + ]; + const result = suggestedPromptIdeas; + const targetSize = 3; + while (result.length < targetSize && defaultPromptIdeas.length) { + result.push(defaultPromptIdeas.pop()); + } return result; }, [suggestedPromptIdeas.length]); return ( - <> +
- - Ideas: + Suggested Ideas:
- { - isPending ? - (
{t('Generating ideas')}...
) : - (
{ideas.map(title => ())}
) - } - + {isPending ? ( +
+ {t('Generating ideas')}... +
+ ) : ( +
+ {ideas.map((title) => ( + + ))} +
+ )} +
); } -function IdeaItem({ title, onClick }: { title: string, onClick: (query: string) => void }) { +function IdeaItem({ + title, + onClick, +}: { + title: string; + onClick: (query: string) => void; +}) { return (
onClick(title)} className={ - 'flex items-center gap-2 cursor-pointer text-gray-dark hover:text-black' + 'cursor-pointer text-gray-dark hover:text-black rounded-full px-4 py-2 shadow border' } > - - {title} + {title}
); } diff --git a/frontend/app/components/Kai/components/IntroSection.tsx b/frontend/app/components/Kai/components/IntroSection.tsx index c6356e9ba..dd28f667a 100644 --- a/frontend/app/components/Kai/components/IntroSection.tsx +++ b/frontend/app/components/Kai/components/IntroSection.tsx @@ -2,24 +2,34 @@ import React from 'react'; import ChatInput from './ChatInput'; import Ideas from './Ideas'; -function IntroSection({ onAsk, projectId }: { onAsk: (query: string) => void, projectId: string }) { +function IntroSection({ + onAsk, + onCancel, + userName, + projectId, +}: { + onAsk: (query: string) => void; + projectId: string; + onCancel: () => void; + userName: string; +}) { const isLoading = false; return ( <> -
- Kai is your AI assistant, delivering smart insights in response to your - queries. -
-
- {/* null} />*/} - +
+
+ Hey {userName}, how can I help you? +
+
onAsk(query)} projectId={projectId} />
-
- OpenReplay AI can make mistakes. Verify its outputs. -
); } diff --git a/frontend/app/components/Modal/index.tsx b/frontend/app/components/Modal/index.tsx index 3b84beeb8..22a531656 100644 --- a/frontend/app/components/Modal/index.tsx +++ b/frontend/app/components/Modal/index.tsx @@ -1,6 +1,7 @@ // @ts-nocheck import React, { Component, createContext } from 'react'; import Modal from './Modal'; +import { className } from '@medv/finder'; const ModalContext = createContext({ component: null, @@ -29,6 +30,7 @@ export class ModalProvider extends Component { this.setState({ component, props, + className: props.className || undefined, }); document.addEventListener('keydown', this.handleKeyDown); document.querySelector('body').style.overflow = 'hidden'; diff --git a/frontend/app/components/shared/SessionItem/SessionItem.tsx b/frontend/app/components/shared/SessionItem/SessionItem.tsx index af42caf1d..23128a84f 100644 --- a/frontend/app/components/shared/SessionItem/SessionItem.tsx +++ b/frontend/app/components/shared/SessionItem/SessionItem.tsx @@ -71,6 +71,7 @@ interface Props { bookmarked?: boolean; toggleFavorite?: (sessionId: string) => void; query?: string; + slim?: boolean; } const PREFETCH_STATE = { @@ -99,6 +100,7 @@ function SessionItem(props: RouteComponentProps & Props) { isDisabled, live: propsLive, isAdd, + slim, } = props; const { @@ -261,7 +263,7 @@ function SessionItem(props: RouteComponentProps & Props) { } >
e.stopPropagation()} onMouseEnter={handleHover} @@ -343,7 +345,7 @@ function SessionItem(props: RouteComponentProps & Props) { : 'Event'}
- + )}
@@ -373,7 +375,7 @@ function SessionItem(props: RouteComponentProps & Props) { )} {userOs && userBrowser && ( - + )} {userOs && ( )} {userOs && ( - + )} + ); +} + +export default Kai_mono; diff --git a/frontend/app/components/ui/SVG.tsx b/frontend/app/components/ui/SVG.tsx index 36dedf09d..e10f6830c 100644 --- a/frontend/app/components/ui/SVG.tsx +++ b/frontend/app/components/ui/SVG.tsx @@ -355,6 +355,7 @@ import { Integrations_vuejs, Integrations_zustand, Journal_code, + Kai_mono, Kai, Kai_colored, Key, @@ -487,7 +488,7 @@ import { Zoom_in } from './Icons' -export type IconNames = 'activity' | 'analytics' | 'anchor' | 'arrow-bar-left' | 'arrow-clockwise' | 'arrow-counterclockwise' | 'arrow-down-short' | 'arrow-down-up' | 'arrow-down' | 'arrow-repeat' | 'arrow-right-short' | 'arrow-up-short' | 'arrow-up' | 'avatar/icn_avatar1' | 'avatar/icn_avatar10' | 'avatar/icn_avatar11' | 'avatar/icn_avatar12' | 'avatar/icn_avatar13' | 'avatar/icn_avatar14' | 'avatar/icn_avatar15' | 'avatar/icn_avatar16' | 'avatar/icn_avatar17' | 'avatar/icn_avatar18' | 'avatar/icn_avatar19' | 'avatar/icn_avatar2' | 'avatar/icn_avatar20' | 'avatar/icn_avatar21' | 'avatar/icn_avatar22' | 'avatar/icn_avatar23' | 'avatar/icn_avatar3' | 'avatar/icn_avatar4' | 'avatar/icn_avatar5' | 'avatar/icn_avatar6' | 'avatar/icn_avatar7' | 'avatar/icn_avatar8' | 'avatar/icn_avatar9' | 'ban' | 'bar-chart-line' | 'bar-pencil' | 'battery-charging' | 'battery' | 'bell-plus' | 'bell-slash' | 'bell' | 'binoculars' | 'book' | 'bookmark' | 'broadcast' | 'browser/browser' | 'browser/chrome' | 'browser/edge' | 'browser/electron' | 'browser/facebook' | 'browser/firefox' | 'browser/ie' | 'browser/opera' | 'browser/safari' | 'buildings' | 'bullhorn' | 'calendar' | 'call' | 'camera-video-off' | 'camera-video' | 'camera' | 'card-list' | 'card-text' | 'caret-down-fill' | 'caret-right-fill' | 'chat-dots' | 'chat-left-text' | 'chat-square-quote' | 'check-circle-fill' | 'check-circle' | 'check' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'circle-fill' | 'circle' | 'click-hesitation' | 'click-rage' | 'clipboard-check' | 'clock-history' | 'clock' | 'close' | 'code' | 'cog' | 'cogs' | 'collection-play' | 'collection' | 'color/apple' | 'color/browser/chrome' | 'color/browser/edge' | 'color/browser/facebook' | 'color/browser/firefox' | 'color/browser/google' | 'color/browser/opera' | 'color/browser/safari' | 'color/browser/unknown' | 'color/browser/whale' | 'color/chrome' | 'color/country/de' | 'color/country/fr' | 'color/country/gb' | 'color/country/in' | 'color/country/us' | 'color/de' | 'color/device/desktop' | 'color/device/mobile' | 'color/device/tablet' | 'color/device/unkown' | 'color/edge' | 'color/fedora' | 'color/firefox' | 'color/fr' | 'color/gb' | 'color/in' | 'color/issues/bad_request' | 'color/issues/click_rage' | 'color/issues/cpu' | 'color/issues/crash' | 'color/issues/custom' | 'color/issues/dead_click' | 'color/issues/errors' | 'color/issues/excessive_scrolling' | 'color/issues/js_exception' | 'color/issues/memory' | 'color/issues/missing_resource' | 'color/issues/mouse_thrashing' | 'color/issues/slow_page_load' | 'color/microsoft' | 'color/opera' | 'color/os/android' | 'color/os/apple' | 'color/os/elementary' | 'color/os/fedora' | 'color/os/ios' | 'color/os/linux' | 'color/os/macos' | 'color/os/microsoft' | 'color/os/ubuntu' | 'color/os/unkown' | 'color/safari' | 'color/ubuntu' | 'color/us' | 'columns-gap' | 'console/error' | 'console/exception' | 'console/info' | 'console/warning' | 'console' | 'controller' | 'cookies' | 'copy' | 'credit-card-2-back' | 'cross' | 'cubes' | 'cursor-trash' | 'cypress' | 'dash' | 'dashboard-icn' | 'dashboards/circle-alert' | 'dashboards/cohort-chart' | 'dashboards/heatmap-2' | 'dashboards/user-journey' | 'db-icons/icn-card-clickMap' | 'db-icons/icn-card-errors' | 'db-icons/icn-card-funnel' | 'db-icons/icn-card-funnels' | 'db-icons/icn-card-insights' | 'db-icons/icn-card-library' | 'db-icons/icn-card-mapchart' | 'db-icons/icn-card-pathAnalysis' | 'db-icons/icn-card-performance' | 'db-icons/icn-card-resources' | 'db-icons/icn-card-table' | 'db-icons/icn-card-timeseries' | 'db-icons/icn-card-webVitals' | 'desktop' | 'device' | 'diagram-3' | 'dizzy' | 'door-closed' | 'download' | 'drag' | 'edit' | 'ellipsis-v' | 'emoji-dizzy' | 'enter' | 'envelope-check' | 'envelope-paper' | 'envelope-x' | 'envelope' | 'errors-icon' | 'event/click' | 'event/click_hesitation' | 'event/clickrage' | 'event/code' | 'event/i-cursor' | 'event/input' | 'event/input_hesitation' | 'event/link' | 'event/location' | 'event/mouse_thrashing' | 'event/resize' | 'event/view' | 'exclamation-circle-fill' | 'exclamation-circle' | 'exclamation-triangle' | 'explosion' | 'external-link-alt' | 'eye-slash-fill' | 'eye-slash' | 'eye' | 'fetch-request' | 'fetch' | 'fflag-multi' | 'fflag-single' | 'file-bar-graph' | 'file-code' | 'file-medical-alt' | 'file-pdf' | 'file' | 'files' | 'filetype-js' | 'filetype-pdf' | 'filter' | 'filters/arrow-return-right' | 'filters/browser' | 'filters/chevrons-up-down' | 'filters/click' | 'filters/clickrage' | 'filters/code' | 'filters/console' | 'filters/country' | 'filters/cpu-load' | 'filters/custom' | 'filters/device' | 'filters/dom-complete' | 'filters/duration' | 'filters/error' | 'filters/fetch-failed' | 'filters/fetch' | 'filters/file-code' | 'filters/graphql' | 'filters/i-cursor' | 'filters/input' | 'filters/lcpt' | 'filters/link' | 'filters/location' | 'filters/memory-load' | 'filters/metadata' | 'filters/os' | 'filters/perfromance-network-request' | 'filters/platform' | 'filters/referrer' | 'filters/resize' | 'filters/rev-id' | 'filters/screen' | 'filters/state-action' | 'filters/tag-element' | 'filters/ttfb' | 'filters/user-alt' | 'filters/userid' | 'filters/view' | 'flag-na' | 'folder-plus' | 'folder2' | 'fullscreen' | 'funnel/cpu-fill' | 'funnel/cpu' | 'funnel/dizzy' | 'funnel/emoji-angry-fill' | 'funnel/emoji-angry' | 'funnel/emoji-dizzy-fill' | 'funnel/exclamation-circle-fill' | 'funnel/exclamation-circle' | 'funnel/file-earmark-break-fill' | 'funnel/file-earmark-break' | 'funnel/file-earmark-minus-fill' | 'funnel/file-earmark-minus' | 'funnel/file-medical-alt' | 'funnel/file-x' | 'funnel/hdd-fill' | 'funnel/hourglass-top' | 'funnel/image-fill' | 'funnel/image' | 'funnel/microchip' | 'funnel/mouse' | 'funnel/patch-exclamation-fill' | 'funnel/sd-card' | 'funnel-fill' | 'funnel' | 'gear' | 'github' | 'graph-up' | 'grid-3x3' | 'grid-check' | 'grid' | 'hash' | 'headset' | 'history' | 'ic-errors' | 'ic-network' | 'ic-rage' | 'ic-resources' | 'icn_fetch-request' | 'icn_referrer' | 'icn_url' | 'id-card' | 'image' | 'info-circle-fill' | 'info-circle' | 'info-square' | 'info' | 'input-hesitation' | 'inspect' | 'integrations/assist' | 'integrations/bugsnag-text' | 'integrations/bugsnag' | 'integrations/cloudwatch-text' | 'integrations/cloudwatch' | 'integrations/datadog' | 'integrations/dynatrace' | 'integrations/elasticsearch-text' | 'integrations/elasticsearch' | 'integrations/github' | 'integrations/graphql' | 'integrations/jira-text' | 'integrations/jira' | 'integrations/mobx' | 'integrations/newrelic-text' | 'integrations/newrelic' | 'integrations/ngrx' | 'integrations/openreplay-text' | 'integrations/openreplay' | 'integrations/redux' | 'integrations/rollbar-text' | 'integrations/rollbar' | 'integrations/segment' | 'integrations/sentry-text' | 'integrations/sentry' | 'integrations/slack-bw' | 'integrations/slack' | 'integrations/stackdriver' | 'integrations/sumologic-text' | 'integrations/sumologic' | 'integrations/teams-white' | 'integrations/teams' | 'integrations/vuejs' | 'integrations/zustand' | 'journal-code' | 'kai' | 'kai_colored' | 'key' | 'keyboard' | 'layers-half' | 'lightbulb-on' | 'lightbulb' | 'link-45deg' | 'list-alt' | 'list-ul' | 'list' | 'low-disc-space' | 'magic' | 'map-marker-alt' | 'memory-ios' | 'memory' | 'metadata-more' | 'mic-mute' | 'mic' | 'minus' | 'mobile' | 'mouse-alt' | 'mouse-pointer-click' | 'network' | 'next1' | 'no-dashboard' | 'no-metrics-chart' | 'no-metrics' | 'no-recordings' | 'orIcn' | 'orSpot' | 'orspotOutline' | 'os/android' | 'os/chrome_os' | 'os/fedora' | 'os/ios' | 'os/linux' | 'os/mac_os_x' | 'os/other' | 'os/ubuntu' | 'os/windows' | 'os' | 'pause-circle-fill' | 'pause-fill' | 'pause' | 'pdf-download' | 'pencil-stop' | 'pencil' | 'people' | 'percent' | 'performance-icon' | 'person-border' | 'person-fill' | 'person' | 'pie-chart-fill' | 'pin-fill' | 'play-circle-bold' | 'play-circle-light' | 'play-circle' | 'play-fill-new' | 'play-fill' | 'play-hover' | 'play' | 'plug' | 'plus-circle' | 'plus' | 'prev1' | 'pulse' | 'puppeteer' | 'puzzle-piece' | 'puzzle' | 'pwright' | 'question-circle' | 'question-lg' | 'quotes' | 'record-circle-fill' | 'record-circle' | 'record2' | 'redo' | 'redux' | 'referrer' | 'remote-control' | 'resources-icon' | 'safe' | 'sandglass' | 'search' | 'server' | 'share-alt' | 'shield-lock' | 'side_menu_closed' | 'side_menu_open' | 'signpost-split' | 'signup' | 'slack' | 'slash-circle' | 'sleep' | 'sliders' | 'social/slack' | 'social/trello' | 'sparkles' | 'speedometer2' | 'spinner' | 'square-mouse-pointer' | 'star' | 'step-forward' | 'stickies' | 'stop-record-circle' | 'stopwatch' | 'store' | 'sync-alt' | 'table' | 'tags' | 'terminal' | 'thermometer-sun' | 'toggles' | 'tools' | 'trash' | 'turtle' | 'user-alt' | 'user-circle' | 'user-friends' | 'user-journey' | 'user-switch' | 'users' | 'vendors/graphql' | 'web-vitals' | 'wifi' | 'window-x' | 'window' | 'zoom-in'; +export type IconNames = 'activity' | 'analytics' | 'anchor' | 'arrow-bar-left' | 'arrow-clockwise' | 'arrow-counterclockwise' | 'arrow-down-short' | 'arrow-down-up' | 'arrow-down' | 'arrow-repeat' | 'arrow-right-short' | 'arrow-up-short' | 'arrow-up' | 'avatar/icn_avatar1' | 'avatar/icn_avatar10' | 'avatar/icn_avatar11' | 'avatar/icn_avatar12' | 'avatar/icn_avatar13' | 'avatar/icn_avatar14' | 'avatar/icn_avatar15' | 'avatar/icn_avatar16' | 'avatar/icn_avatar17' | 'avatar/icn_avatar18' | 'avatar/icn_avatar19' | 'avatar/icn_avatar2' | 'avatar/icn_avatar20' | 'avatar/icn_avatar21' | 'avatar/icn_avatar22' | 'avatar/icn_avatar23' | 'avatar/icn_avatar3' | 'avatar/icn_avatar4' | 'avatar/icn_avatar5' | 'avatar/icn_avatar6' | 'avatar/icn_avatar7' | 'avatar/icn_avatar8' | 'avatar/icn_avatar9' | 'ban' | 'bar-chart-line' | 'bar-pencil' | 'battery-charging' | 'battery' | 'bell-plus' | 'bell-slash' | 'bell' | 'binoculars' | 'book' | 'bookmark' | 'broadcast' | 'browser/browser' | 'browser/chrome' | 'browser/edge' | 'browser/electron' | 'browser/facebook' | 'browser/firefox' | 'browser/ie' | 'browser/opera' | 'browser/safari' | 'buildings' | 'bullhorn' | 'calendar' | 'call' | 'camera-video-off' | 'camera-video' | 'camera' | 'card-list' | 'card-text' | 'caret-down-fill' | 'caret-right-fill' | 'chat-dots' | 'chat-left-text' | 'chat-square-quote' | 'check-circle-fill' | 'check-circle' | 'check' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'circle-fill' | 'circle' | 'click-hesitation' | 'click-rage' | 'clipboard-check' | 'clock-history' | 'clock' | 'close' | 'code' | 'cog' | 'cogs' | 'collection-play' | 'collection' | 'color/apple' | 'color/browser/chrome' | 'color/browser/edge' | 'color/browser/facebook' | 'color/browser/firefox' | 'color/browser/google' | 'color/browser/opera' | 'color/browser/safari' | 'color/browser/unknown' | 'color/browser/whale' | 'color/chrome' | 'color/country/de' | 'color/country/fr' | 'color/country/gb' | 'color/country/in' | 'color/country/us' | 'color/de' | 'color/device/desktop' | 'color/device/mobile' | 'color/device/tablet' | 'color/device/unkown' | 'color/edge' | 'color/fedora' | 'color/firefox' | 'color/fr' | 'color/gb' | 'color/in' | 'color/issues/bad_request' | 'color/issues/click_rage' | 'color/issues/cpu' | 'color/issues/crash' | 'color/issues/custom' | 'color/issues/dead_click' | 'color/issues/errors' | 'color/issues/excessive_scrolling' | 'color/issues/js_exception' | 'color/issues/memory' | 'color/issues/missing_resource' | 'color/issues/mouse_thrashing' | 'color/issues/slow_page_load' | 'color/microsoft' | 'color/opera' | 'color/os/android' | 'color/os/apple' | 'color/os/elementary' | 'color/os/fedora' | 'color/os/ios' | 'color/os/linux' | 'color/os/macos' | 'color/os/microsoft' | 'color/os/ubuntu' | 'color/os/unkown' | 'color/safari' | 'color/ubuntu' | 'color/us' | 'columns-gap' | 'console/error' | 'console/exception' | 'console/info' | 'console/warning' | 'console' | 'controller' | 'cookies' | 'copy' | 'credit-card-2-back' | 'cross' | 'cubes' | 'cursor-trash' | 'cypress' | 'dash' | 'dashboard-icn' | 'dashboards/circle-alert' | 'dashboards/cohort-chart' | 'dashboards/heatmap-2' | 'dashboards/user-journey' | 'db-icons/icn-card-clickMap' | 'db-icons/icn-card-errors' | 'db-icons/icn-card-funnel' | 'db-icons/icn-card-funnels' | 'db-icons/icn-card-insights' | 'db-icons/icn-card-library' | 'db-icons/icn-card-mapchart' | 'db-icons/icn-card-pathAnalysis' | 'db-icons/icn-card-performance' | 'db-icons/icn-card-resources' | 'db-icons/icn-card-table' | 'db-icons/icn-card-timeseries' | 'db-icons/icn-card-webVitals' | 'desktop' | 'device' | 'diagram-3' | 'dizzy' | 'door-closed' | 'download' | 'drag' | 'edit' | 'ellipsis-v' | 'emoji-dizzy' | 'enter' | 'envelope-check' | 'envelope-paper' | 'envelope-x' | 'envelope' | 'errors-icon' | 'event/click' | 'event/click_hesitation' | 'event/clickrage' | 'event/code' | 'event/i-cursor' | 'event/input' | 'event/input_hesitation' | 'event/link' | 'event/location' | 'event/mouse_thrashing' | 'event/resize' | 'event/view' | 'exclamation-circle-fill' | 'exclamation-circle' | 'exclamation-triangle' | 'explosion' | 'external-link-alt' | 'eye-slash-fill' | 'eye-slash' | 'eye' | 'fetch-request' | 'fetch' | 'fflag-multi' | 'fflag-single' | 'file-bar-graph' | 'file-code' | 'file-medical-alt' | 'file-pdf' | 'file' | 'files' | 'filetype-js' | 'filetype-pdf' | 'filter' | 'filters/arrow-return-right' | 'filters/browser' | 'filters/chevrons-up-down' | 'filters/click' | 'filters/clickrage' | 'filters/code' | 'filters/console' | 'filters/country' | 'filters/cpu-load' | 'filters/custom' | 'filters/device' | 'filters/dom-complete' | 'filters/duration' | 'filters/error' | 'filters/fetch-failed' | 'filters/fetch' | 'filters/file-code' | 'filters/graphql' | 'filters/i-cursor' | 'filters/input' | 'filters/lcpt' | 'filters/link' | 'filters/location' | 'filters/memory-load' | 'filters/metadata' | 'filters/os' | 'filters/perfromance-network-request' | 'filters/platform' | 'filters/referrer' | 'filters/resize' | 'filters/rev-id' | 'filters/screen' | 'filters/state-action' | 'filters/tag-element' | 'filters/ttfb' | 'filters/user-alt' | 'filters/userid' | 'filters/view' | 'flag-na' | 'folder-plus' | 'folder2' | 'fullscreen' | 'funnel/cpu-fill' | 'funnel/cpu' | 'funnel/dizzy' | 'funnel/emoji-angry-fill' | 'funnel/emoji-angry' | 'funnel/emoji-dizzy-fill' | 'funnel/exclamation-circle-fill' | 'funnel/exclamation-circle' | 'funnel/file-earmark-break-fill' | 'funnel/file-earmark-break' | 'funnel/file-earmark-minus-fill' | 'funnel/file-earmark-minus' | 'funnel/file-medical-alt' | 'funnel/file-x' | 'funnel/hdd-fill' | 'funnel/hourglass-top' | 'funnel/image-fill' | 'funnel/image' | 'funnel/microchip' | 'funnel/mouse' | 'funnel/patch-exclamation-fill' | 'funnel/sd-card' | 'funnel-fill' | 'funnel' | 'gear' | 'github' | 'graph-up' | 'grid-3x3' | 'grid-check' | 'grid' | 'hash' | 'headset' | 'history' | 'ic-errors' | 'ic-network' | 'ic-rage' | 'ic-resources' | 'icn_fetch-request' | 'icn_referrer' | 'icn_url' | 'id-card' | 'image' | 'info-circle-fill' | 'info-circle' | 'info-square' | 'info' | 'input-hesitation' | 'inspect' | 'integrations/assist' | 'integrations/bugsnag-text' | 'integrations/bugsnag' | 'integrations/cloudwatch-text' | 'integrations/cloudwatch' | 'integrations/datadog' | 'integrations/dynatrace' | 'integrations/elasticsearch-text' | 'integrations/elasticsearch' | 'integrations/github' | 'integrations/graphql' | 'integrations/jira-text' | 'integrations/jira' | 'integrations/mobx' | 'integrations/newrelic-text' | 'integrations/newrelic' | 'integrations/ngrx' | 'integrations/openreplay-text' | 'integrations/openreplay' | 'integrations/redux' | 'integrations/rollbar-text' | 'integrations/rollbar' | 'integrations/segment' | 'integrations/sentry-text' | 'integrations/sentry' | 'integrations/slack-bw' | 'integrations/slack' | 'integrations/stackdriver' | 'integrations/sumologic-text' | 'integrations/sumologic' | 'integrations/teams-white' | 'integrations/teams' | 'integrations/vuejs' | 'integrations/zustand' | 'journal-code' | 'kai-mono' | 'kai' | 'kai_colored' | 'key' | 'keyboard' | 'layers-half' | 'lightbulb-on' | 'lightbulb' | 'link-45deg' | 'list-alt' | 'list-ul' | 'list' | 'low-disc-space' | 'magic' | 'map-marker-alt' | 'memory-ios' | 'memory' | 'metadata-more' | 'mic-mute' | 'mic' | 'minus' | 'mobile' | 'mouse-alt' | 'mouse-pointer-click' | 'network' | 'next1' | 'no-dashboard' | 'no-metrics-chart' | 'no-metrics' | 'no-recordings' | 'orIcn' | 'orSpot' | 'orspotOutline' | 'os/android' | 'os/chrome_os' | 'os/fedora' | 'os/ios' | 'os/linux' | 'os/mac_os_x' | 'os/other' | 'os/ubuntu' | 'os/windows' | 'os' | 'pause-circle-fill' | 'pause-fill' | 'pause' | 'pdf-download' | 'pencil-stop' | 'pencil' | 'people' | 'percent' | 'performance-icon' | 'person-border' | 'person-fill' | 'person' | 'pie-chart-fill' | 'pin-fill' | 'play-circle-bold' | 'play-circle-light' | 'play-circle' | 'play-fill-new' | 'play-fill' | 'play-hover' | 'play' | 'plug' | 'plus-circle' | 'plus' | 'prev1' | 'pulse' | 'puppeteer' | 'puzzle-piece' | 'puzzle' | 'pwright' | 'question-circle' | 'question-lg' | 'quotes' | 'record-circle-fill' | 'record-circle' | 'record2' | 'redo' | 'redux' | 'referrer' | 'remote-control' | 'resources-icon' | 'safe' | 'sandglass' | 'search' | 'server' | 'share-alt' | 'shield-lock' | 'side_menu_closed' | 'side_menu_open' | 'signpost-split' | 'signup' | 'slack' | 'slash-circle' | 'sleep' | 'sliders' | 'social/slack' | 'social/trello' | 'sparkles' | 'speedometer2' | 'spinner' | 'square-mouse-pointer' | 'star' | 'step-forward' | 'stickies' | 'stop-record-circle' | 'stopwatch' | 'store' | 'sync-alt' | 'table' | 'tags' | 'terminal' | 'thermometer-sun' | 'toggles' | 'tools' | 'trash' | 'turtle' | 'user-alt' | 'user-circle' | 'user-friends' | 'user-journey' | 'user-switch' | 'users' | 'vendors/graphql' | 'web-vitals' | 'wifi' | 'window-x' | 'window' | 'zoom-in'; interface Props { name: IconNames; @@ -1561,6 +1562,9 @@ const SVG = (props: Props) => { // case 'journal-code': case 'journal-code': return ; + // case 'kai-mono': + case 'kai-mono': return ; + case 'kai': return ; diff --git a/frontend/app/svg/icons/kai-mono.svg b/frontend/app/svg/icons/kai-mono.svg new file mode 100644 index 000000000..97738455d --- /dev/null +++ b/frontend/app/svg/icons/kai-mono.svg @@ -0,0 +1,11 @@ + + + + + + + + + + +