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

Upgrade: New Home Screen for Khoj #860

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
8ba79fc
V1 of the new automations page
sabaimran Jul 12, 2024
05bf911
Improve notice of which email address is being delivered to
sabaimran Jul 12, 2024
a8d4b8f
Fix validation bugs in the edit form
sabaimran Jul 13, 2024
ce99c48
Remove console logs for debugging
sabaimran Jul 13, 2024
9c553b9
Fix spacing in page css
sabaimran Jul 13, 2024
eaab311
Fix spaving in nav menu
sabaimran Jul 13, 2024
a830839
Remove syntax import for highlight.js in code
sabaimran Jul 13, 2024
0213848
Manually insert preferred styling for light/dark mode from highlight.…
sabaimran Jul 13, 2024
6ea3746
Fix copy button rendering issue (it disappears if you've hovered on t…
sabaimran Jul 13, 2024
f3c5deb
Fix some linting errors with unescaped characters on the automations …
sabaimran Jul 13, 2024
eaf924e
Add an alert pane showing the email, location for automations
sabaimran Jul 13, 2024
201a5d7
Merge branch 'features/chat-ui-updates-big' of github.com:khoj-ai/kho…
sabaimran Jul 13, 2024
05b616d
Add more icons and add a left bar for styling on each individual auto…
sabaimran Jul 13, 2024
ccbfc4a
Add support for setting color and icons on the agents in the backend
sabaimran Jul 13, 2024
07ead01
Migrate agents page to use the new shadcn component library and the c…
sabaimran Jul 13, 2024
4f7fe3e
Update styling of cards
sabaimran Jul 13, 2024
2e43c2e
Fix dark/light mode toggle rendering bug
sabaimran Jul 13, 2024
a22c1da
Remove dead styling
sabaimran Jul 13, 2024
d2afe26
Navigate nav urls within same page, add an info piece to the agents page
sabaimran Jul 14, 2024
4243419
Merge branch 'features/big-upgrade-chat-ux' of github.com:khoj-ai/kho…
sabaimran Jul 14, 2024
a69e3e3
Merge branch 'features/big-upgrade-chat-ux' of github.com:khoj-ai/kho…
sabaimran Jul 15, 2024
c976315
Revert packages removed in merging
sabaimran Jul 15, 2024
a771c6f
Merge branch 'features/big-upgrade-chat-ux' of github.com:khoj-ai/kho…
sabaimran Jul 15, 2024
9288fb1
Merge branch 'features/update-automations-page' of github.com:khoj-ai…
sabaimran Jul 15, 2024
ccc145c
simplify conditional with ternary operator
sabaimran Jul 15, 2024
7945471
Merge branch 'features/big-upgrade-chat-ux' of github.com:khoj-ai/kho…
sabaimran Jul 15, 2024
3de92b0
rough draft of khoj homepage finished!
MythicalCow Jul 15, 2024
a5f91a9
Merge remote-tracking branch 'upstream/features/big-upgrade-chat-ux' …
MythicalCow Jul 16, 2024
da11415
UI completed and ready for review. working on mechanics
MythicalCow Jul 16, 2024
ca2b430
bugs on some things
MythicalCow Jul 17, 2024
60fc4d5
UI cleanup and phosphor icons integration. backend in progress but hi…
MythicalCow Jul 18, 2024
c621548
agents fix causing chat flow issue
MythicalCow Jul 18, 2024
c207940
removing localConversationId trial
MythicalCow Jul 18, 2024
ac3cdb9
removing localConversationId trial
MythicalCow Jul 18, 2024
0529001
fixed new conversation gen from homepage
MythicalCow Jul 18, 2024
76eb8fc
homepage changes?
MythicalCow Jul 18, 2024
4c116d5
non crashing homepage. (currently non-functional)
MythicalCow Jul 18, 2024
94b0fe5
working new page screen
MythicalCow Jul 18, 2024
2dfa092
removed debug button
MythicalCow Jul 18, 2024
1f996af
added support for autofilling text based suggestions
MythicalCow Jul 18, 2024
b8b4c1e
added small local storage fix
MythicalCow Jul 18, 2024
7b0c7da
fixed double message glitch
MythicalCow Jul 18, 2024
203b4db
made connection status in side panel connected for homepage
MythicalCow Jul 18, 2024
56d306c
changed menu icon based on figma
MythicalCow Jul 18, 2024
80a36f3
added side panel new conversation button
MythicalCow Jul 18, 2024
5d4c132
added centering for main page items
MythicalCow Jul 18, 2024
00791a6
homepage mostly finished. agents still isn't getting sent over during…
MythicalCow Jul 19, 2024
eb716c3
homepage finished! code cleanup remains
MythicalCow Jul 19, 2024
3368742
code cleaned up :)
MythicalCow Jul 19, 2024
85e811b
placed home page on / instead of /home for debugging. /home functional
MythicalCow Jul 19, 2024
784edd8
removed old agentShortcut
MythicalCow Jul 19, 2024
5f68731
removed excessive logging
MythicalCow Jul 19, 2024
a08e58f
additional code cleaning
MythicalCow Jul 19, 2024
1668f8d
small fix for suggestions
MythicalCow Jul 19, 2024
4eae39f
Remove yarn.lock
sabaimran Jul 21, 2024
eccb849
resolve updates with latest yarn.lock
sabaimran Jul 21, 2024
20c7b9c
Small updates to overall styling and components usage for homepage
sabaimran Jul 21, 2024
68b3801
Resolve merge conflicts
sabaimran Jul 21, 2024
e56ee3b
Implement mobile-friendly view for homepage
sabaimran Jul 21, 2024
08dbc25
Fix issue of new conversations being created when selected agent is c…
sabaimran Jul 21, 2024
8442fe6
Improve center of the homepage experience
sabaimran Jul 21, 2024
6fcbbfb
Fix showing agent during first chat experience
sabaimran Jul 21, 2024
82750d3
update profile card in chat history to use tooltip
sabaimran Jul 21, 2024
bae2164
Fix errors for missing key prop react
sabaimran Jul 22, 2024
9f4374d
removed legacy svgs and moved /home page to /
MythicalCow Jul 22, 2024
2da12a8
Merge branch 'homescreen-ui' of https://github.com/MythicalCow/khoj i…
MythicalCow Jul 22, 2024
f276352
removing weird formatting errors
MythicalCow Jul 22, 2024
22e96fe
dark mode upgrades
MythicalCow Jul 22, 2024
b650d1f
agent highlighting simplification
MythicalCow Jul 22, 2024
7610906
dark mode gradient updates
MythicalCow Jul 23, 2024
546af11
fixed mobile width issues and used cards for agents
MythicalCow Jul 23, 2024
b810a21
fixed mobile width issues and used cards for agents!
MythicalCow Jul 23, 2024
67902a2
merge mobile changes
MythicalCow Jul 23, 2024
7636e70
mobile changes merge conflict resolution
MythicalCow Jul 23, 2024
1ebec5e
moved icon and tailwind color functionalities into util imports
MythicalCow Jul 23, 2024
264a016
moved util files to /common
MythicalCow Jul 23, 2024
397b901
Improve layout with side panel, resolve issues with mobile rendering,…
sabaimran Jul 24, 2024
ca63f14
Re-use common functions for css in suggestionscard
sabaimran Jul 24, 2024
e0bdf7e
Simplify package versions and address missing key react errors
sabaimran Jul 24, 2024
66a4f69
Improve dark mode for chat input area on home page, chat
sabaimran Jul 24, 2024
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
7 changes: 4 additions & 3 deletions src/interface/web/app/agents/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ async function openChat(slug: string, userData: UserProfile | null) {
}

const response = await fetch(`/api/chat/sessions?agent_slug=${slug}`, { method: "POST" });
const data = await response.json();
if (response.status == 200) {
window.location.href = `/chat`;
window.location.href = `/chat?conversationId=${data.conversation_id}`;
} else if (response.status == 403 || response.status == 401) {
window.location.href = unauthenticatedRedirectUrl;
} else {
Expand Down Expand Up @@ -294,7 +295,7 @@ export default function Agents() {
return (
<main className={styles.main}>
<div className={`${styles.titleBar} text-5xl`}>
Talk to a Specialized Agent
Agents
</div>
<div className={styles.agentList}>
Error loading agents
Expand All @@ -307,7 +308,7 @@ export default function Agents() {
return (
<main className={styles.main}>
<div className={`${styles.titleBar} text-5xl`}>
Talk to a Specialized Agent
Agents
</div>
<div className={styles.agentList}>
<InlineLoading /> booting up your agents
Expand Down
40 changes: 37 additions & 3 deletions src/interface/web/app/chat/chat.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ div.main {
}

.suggestions {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
display: flex;
overflow-x: none;
height: 50%;
padding: 10px;
white-space: nowrap;
/* grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); */
gap: 1rem;
justify-content: center;
/* justify-content: center; */
}

div.inputBox {
Expand Down Expand Up @@ -124,3 +128,33 @@ div.agentIndicator {
}

}

#pink {
MythicalCow marked this conversation as resolved.
Show resolved Hide resolved
background-color: #f8d1f8;
color: #000000;
background-image: linear-gradient(to top, #f8d1f8 1%, white 100%);
}

#blue {
background-color: #d1f8f8;
color: #000000;
background-image: linear-gradient(to top, #d1f8f8 1%, white 100%);
}

#green {
background-color: #d1f8d1;
color: #000000;
background-image: linear-gradient(to top, #d1f8d1 1%, white 100%);
}

#purple {
background-color: #f8d1f8;
color: #000000;
background-image: linear-gradient(to top, #f8d1f8 1%, white 100%);
}

#yellow {
background-color: #f8f8d1;
color: #000000;
background-image: linear-gradient(to top, #f8f8d1 1%, white 100%);
}
111 changes: 61 additions & 50 deletions src/interface/web/app/chat/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import styles from './chat.module.css';
import React, { Suspense, useEffect, useState } from 'react';

import SuggestionCard from '../components/suggestions/suggestionCard';
import SidePanel from '../components/sidePanel/chatHistorySidePanel';
import ChatHistory from '../components/chatHistory/chatHistory';
import NavMenu from '../components/navMenu/navMenu';
Expand All @@ -19,9 +18,6 @@ import { welcomeConsole } from '../common/utils';
import ChatInputArea, { ChatOptions } from '../components/chatInputArea/chatInputArea';
import { useAuthenticatedData } from '../common/auth';


const styleClassOptions = ['pink', 'blue', 'green', 'yellow', 'purple'];

interface ChatBodyDataProps {
chatOptionsData: ChatOptions | null;
setTitle: (title: string) => void;
Expand All @@ -40,43 +36,38 @@ function ChatBodyData(props: ChatBodyDataProps) {
const [processingMessage, setProcessingMessage] = useState(false);

useEffect(() => {
if (conversationId) {
props.onConversationIdChange?.(conversationId);
const storedMessage = localStorage.getItem("message");
if (storedMessage) {
setMessage(storedMessage);
}
}, [conversationId, props.onConversationIdChange]);
}, []);

useEffect(() => {
if (message) {
if(message){
setProcessingMessage(true);
props.setQueryToProcess(message);
}
}, [message]);

useEffect(() => {
if (conversationId) {
props.onConversationIdChange?.(conversationId);
}
}, [conversationId]);

useEffect(() => {
if (props.streamedMessages &&
props.streamedMessages.length > 0 &&
props.streamedMessages[props.streamedMessages.length - 1].completed) {

setProcessingMessage(false);
} else {
setMessage('');
}
}, [props.streamedMessages]);

if (!conversationId) {
return (
<div className={styles.suggestions}>
{props.chatOptionsData && Object.entries(props.chatOptionsData).map(([key, value]) => (
<SuggestionCard
key={key}
title={`/${key}`}
body={value}
link='#' // replace with actual link if available
styleClass={styleClassOptions[Math.floor(Math.random() * styleClassOptions.length)]}
/>
))}
</div>
);
if(!conversationId) {
window.location.href = '/';
return;
}

return (
Expand All @@ -88,7 +79,7 @@ function ChatBodyData(props: ChatBodyDataProps) {
pendingMessage={processingMessage ? message : ''}
incomingMessages={props.streamedMessages} />
</div>
<div className={`${styles.inputBox} bg-background align-middle items-center justify-center px-3`}>
<div className={`${styles.inputBox} bg-background align-middle items-center justify-center px-3 dark:bg-neutral-700 dark:border-0 dark:shadow-sm`}>
<ChatInputArea
isLoggedIn={props.isLoggedIn}
sendMessage={(message) => setMessage(message)}
Expand Down Expand Up @@ -121,7 +112,6 @@ export default function Chat() {
const handleWebSocketMessage = (event: MessageEvent) => {
let chunk = event.data;
let currentMessage = messages.find(message => !message.completed);

if (!currentMessage) {
console.error("No current message found");
return;
Expand Down Expand Up @@ -204,52 +194,73 @@ export default function Chat() {

}, []);

useEffect(() => {
if (chatWS) {
chatWS.onmessage = handleWebSocketMessage;
}
}, [chatWS, messages]);

//same as ChatBodyData for local storage message
useEffect(() => {
const storedMessage = localStorage.getItem("message");
setQueryToProcess(storedMessage || '');
}, []);

useEffect(() => {
if (chatWS && queryToProcess) {
// Add a new object to the state
const newStreamMessage: StreamMessage = {
rawResponse: "",
trainOfThought: [],
context: [],
onlineContext: {},
completed: false,
timestamp: (new Date()).toISOString(),
rawQuery: queryToProcess || "",
}
rawResponse: "",
trainOfThought: [],
context: [],
onlineContext: {},
completed: false,
timestamp: (new Date()).toISOString(),
rawQuery: queryToProcess || "",
};
setMessages(prevMessages => [...prevMessages, newStreamMessage]);
setProcessQuerySignal(true);
} else {
if (!chatWS) {
console.error("No WebSocket connection available");

if (chatWS.readyState === WebSocket.OPEN) {
chatWS.send(queryToProcess);
setProcessQuerySignal(true);
}
if (!queryToProcess) {
console.error("No query to process");
else {
console.error("WebSocket is not open. ReadyState:", chatWS.readyState);
}

setQueryToProcess('');
}
}, [queryToProcess]);
}, [queryToProcess, chatWS]);

useEffect(() => {
if (processQuerySignal && chatWS) {
useEffect(() => {
if (processQuerySignal && chatWS && chatWS.readyState === WebSocket.OPEN) {
setProcessQuerySignal(false);
chatWS.onmessage = handleWebSocketMessage;
chatWS?.send(queryToProcess);
chatWS.send(queryToProcess);
localStorage.removeItem("message");
}
}, [processQuerySignal]);
}, [processQuerySignal, chatWS]);

useEffect(() => {
(async () => {
if (conversationId) {
const setupWebSocketConnection = async () => {
if (conversationId && (!chatWS || chatWS.readyState === WebSocket.CLOSED)) {
if(queryToProcess) {
const newWS = await setupWebSocket(conversationId, queryToProcess);
localStorage.removeItem("message");
setChatWS(newWS);
}
else {
const newWS = await setupWebSocket(conversationId);
setChatWS(newWS);
}
})();
}
};
setupWebSocketConnection();
}, [conversationId]);

const handleConversationIdChange = (newConversationId: string) => {
setConversationID(newConversationId);
};


if (isLoading) {
return <Loading />;
}
Expand All @@ -260,7 +271,7 @@ export default function Chat() {
<title>
{title}
</title>
<div className={styles.sidePanel}>
<div>
<SidePanel
webSocketConnected={chatWS !== null}
conversationId={conversationId}
Expand Down
4 changes: 3 additions & 1 deletion src/interface/web/app/common/chatFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ export const setupWebSocket = async (conversationId: string, initialMessage?: st

let webSocketUrl = `${wsProtocol}//${host}/api/chat/ws`;

if (conversationId === null) return null;
if (conversationId === null) {
return null;
}

if (conversationId) {
webSocketUrl += `?conversation_id=${conversationId}`;
Expand Down
60 changes: 60 additions & 0 deletions src/interface/web/app/common/colorUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
export function convertColorToTextClass(color: string) {
if (color === 'red') return `text-red-500`;
if (color === 'yellow') return `text-yellow-500`;
if (color === 'green') return `text-green-500`;
if (color === 'blue') return `text-blue-500`;
if (color === 'orange') return `text-orange-500`;
if (color === 'purple') return `text-purple-500`;
if (color === 'pink') return `text-pink-500`;
if (color === 'teal') return `text-teal-500`;
if (color === 'cyan') return `text-cyan-500`;
if (color === 'lime') return `text-lime-500`;
if (color === 'indigo') return `text-indigo-500`;
if (color === 'fuschia') return `text-fuschia-500`;
if (color === 'rose') return `text-rose-500`;
if (color === 'sky') return `text-sky-500`;
if (color === 'amber') return `text-amber-500`;
if (color === 'emerald') return `text-emerald-500`;
return `text-gray-500`;
}

export function convertSuggestionColorToTextClass(color: string) {
const colors = ['blue', 'yellow', 'green', 'pink', 'purple'];
if (colors.includes(color)) {
return "" + `bg-gradient-to-b from-[hsl(var(--background))] to-${color}-100/${color == "green" ? "90" : "70"} dark:from-[hsl(var(--background))] dark:to-${color}-950/30 dark:border dark:border-neutral-700`;
}
return `bg-gradient-to-b from-white to-orange-50`;
}

export function convertColorToBorderClass(color: string) {
console.log("Color:", color);
if (color === 'red') return `border-red-500`;
if (color === 'yellow') return `border-yellow-500`;
if (color === 'green') return `border-green-500`;
if (color === 'blue') return `border-blue-500`;
if (color === 'orange') return `border-orange-500`;
if (color === 'purple') return `border-purple-500`;
if (color === 'pink') return `border-pink-500`;
if (color === 'teal') return `border-teal-500`;
if (color === 'cyan') return `border-cyan-500`;
if (color === 'lime') return `border-lime-500`;
if (color === 'indigo') return `border-indigo-500`;
if (color === 'fuschia') return `border-fuschia-500`;
if (color === 'rose') return `border-rose-500`;
if (color === 'sky') return `border-sky-500`;
if (color === 'amber') return `border-amber-500`;
if (color === 'emerald') return `border-emerald-500`;
return `border-gray-500`;
}

export const colorMap: Record<string, string> = {
'red': 'border-red-500',
'blue': 'border-blue-500',
'green': 'border-green-500',
'yellow': 'border-yellow-500',
'purple': 'border-purple-500',
'pink': 'border-pink-500',
'indigo': 'border-indigo-500',
'gray': 'border-gray-500',
'orange': 'border-orange-500',
};
Loading
Loading