From d3c07a098d8f6fd808bd2fb0cc317f8786c9ade9 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 17:46:13 +0530 Subject: [PATCH 01/53] Update nav menu styling to include everything in one header - Move the nav menu into the chat history side panel component, so that they both show up on one line - Update all pages to use it with the new formatting - in mobile, present the sidebar button, home button, and profile button evenly centered in the middle --- .../web/app/agents/agents.module.css | 7 +- src/interface/web/app/agents/page.tsx | 5 +- .../app/automations/automations.module.css | 5 + src/interface/web/app/automations/page.tsx | 5 +- src/interface/web/app/chat/page.tsx | 36 +++- .../app/components/navMenu/navMenu.module.css | 4 - .../web/app/components/navMenu/navMenu.tsx | 30 +--- .../sidePanel/chatHistorySidePanel.tsx | 38 ++-- .../components/sidePanel/sidePanel.module.css | 6 +- src/interface/web/app/page.module.css | 16 +- src/interface/web/app/page.tsx | 8 +- src/interface/web/app/search/page.tsx | 167 +++++++++--------- .../web/app/search/search.module.css | 12 +- 13 files changed, 182 insertions(+), 157 deletions(-) diff --git a/src/interface/web/app/agents/agents.module.css b/src/interface/web/app/agents/agents.module.css index 8433a88f..73cbd7a3 100644 --- a/src/interface/web/app/agents/agents.module.css +++ b/src/interface/web/app/agents/agents.module.css @@ -46,7 +46,7 @@ div.agentList { } -@media only screen and (max-width: 700px) { +@media only screen and (max-width: 768px) { div.agentList { width: 100%; padding: 0; @@ -54,4 +54,9 @@ div.agentList { margin-left: auto; grid-template-columns: 1fr; } + + div.sidePanel { + position: relative; + height: 100%; + } } diff --git a/src/interface/web/app/agents/page.tsx b/src/interface/web/app/agents/page.tsx index 5e68a0b9..8a9f955a 100644 --- a/src/interface/web/app/agents/page.tsx +++ b/src/interface/web/app/agents/page.tsx @@ -266,9 +266,6 @@ export default function Agents() { return (
-
- -
{ showLoginPrompt &&
-
+

Agents

diff --git a/src/interface/web/app/automations/automations.module.css b/src/interface/web/app/automations/automations.module.css index 99f094c3..f0c35244 100644 --- a/src/interface/web/app/automations/automations.module.css +++ b/src/interface/web/app/automations/automations.module.css @@ -28,4 +28,9 @@ div.sidePanel { div.pageLayout { max-width: 90vw; } + + div.sidePanel { + position: relative; + height: 100%; + } } diff --git a/src/interface/web/app/automations/page.tsx b/src/interface/web/app/automations/page.tsx index 9416cee7..c933f8fd 100644 --- a/src/interface/web/app/automations/page.tsx +++ b/src/interface/web/app/automations/page.tsx @@ -936,9 +936,6 @@ export default function Automations() { return (
-
- -
-

Automations

+

Automations

{ authenticatedData ? ( diff --git a/src/interface/web/app/chat/page.tsx b/src/interface/web/app/chat/page.tsx index 1768a228..702dc894 100644 --- a/src/interface/web/app/chat/page.tsx +++ b/src/interface/web/app/chat/page.tsx @@ -196,7 +196,7 @@ export default function Chat() { } // Track context used for chat response. References are rendered at the end of the chat - ({context, onlineContext} = processMessageChunk(event, currentMessage, context, onlineContext)); + ({ context, onlineContext } = processMessageChunk(event, currentMessage, context, onlineContext)); setMessages([...messages]); } @@ -231,16 +231,34 @@ export default function Chat() { {title} -
- -
+ { + !isMobileWidth && +
+ +
+ }
- + { + isMobileWidth && +
+ +
+ }
+ { + !isMobileWidth && +
+ {title &&

{title}

} +
+ } }> (props.title); - const [isMobileWidth, setIsMobileWidth] = useState(false); const [darkMode, setDarkMode] = useState(false); const [initialLoadDone, setInitialLoadDone] = useState(false); useEffect(() => { setIsMobileWidth(window.innerWidth < 768); - if (props.title) { - setDisplayTitle(props.title); - } else if (!props.title) { - setDisplayTitle(undefined); - } - - }, [props.title]); - - useEffect(() => { window.addEventListener('resize', () => { setIsMobileWidth(window.innerWidth < 768); @@ -94,15 +75,6 @@ export default function NavMenu(props: NavMenuProps) { return (
-
- {displayTitle &&

{displayTitle}

} - { - !displayTitle && props.showLogo && - - - - } -
{ isMobileWidth ? diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index b02ea754..00e5e26c 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -76,6 +76,7 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, import { modifyFileFilterForConversation } from "@/app/common/chatFunctions"; import { ScrollAreaScrollbar } from "@radix-ui/react-scroll-area"; import { KhojLogo, KhojLogoType } from "@/app/components/logo/khogLogo"; +import NavMenu from "../navMenu/navMenu"; // Define a fetcher function const fetcher = (url: string) => fetch(url).then((res) => res.json()); @@ -660,11 +661,8 @@ export default function SidePanel(props: SidePanelProps) { }, [chatSessions]); return ( -
+
- - {props.isMobileWidth && || } - { authenticatedData && props.isMobileWidth ? { @@ -672,7 +670,7 @@ export default function SidePanel(props: SidePanelProps) { setEnabled(open); } }> - + Sessions and Files @@ -698,15 +696,33 @@ export default function SidePanel(props: SidePanelProps) { : -
- - {enabled ? : } +
+ + - +
+ + {enabled ? : } + + +
+
+ +
} + { + props.isMobileWidth && + + + + } + { + props.isMobileWidth && + + }
{ authenticatedData && !props.isMobileWidth && enabled && diff --git a/src/interface/web/app/components/sidePanel/sidePanel.module.css b/src/interface/web/app/components/sidePanel/sidePanel.module.css index 77fddd13..e984eb6a 100644 --- a/src/interface/web/app/components/sidePanel/sidePanel.module.css +++ b/src/interface/web/app/components/sidePanel/sidePanel.module.css @@ -123,9 +123,9 @@ div.modalSessionsList div.session { @media screen and (max-width: 768px) { div.panel { - padding: 0.5rem; - position: fixed; - width: fit-content; + padding: 0.25rem; + /* position: fixed; */ + width: 100%; } div.expanded { diff --git a/src/interface/web/app/page.module.css b/src/interface/web/app/page.module.css index 32c89473..0f02c77a 100644 --- a/src/interface/web/app/page.module.css +++ b/src/interface/web/app/page.module.css @@ -78,7 +78,13 @@ div.chatBoxBody { display: grid; height: 100%; margin: auto; - grid-template-rows: auto 1fr; +} + +div.homeGreetings { + display: grid; + height: 100%; + margin: auto; + grid-template-rows: 1fr 2fr; } @@ -108,6 +114,10 @@ div.sidePanel { grid-template-rows: auto; } + div.sidePanel { + position: relative; + } + div.chatBox { padding: 0; } @@ -117,4 +127,8 @@ div.sidePanel { grid-template-columns: 1fr; } + div.homeGreetings { + grid-template-rows: auto; + } + } diff --git a/src/interface/web/app/page.tsx b/src/interface/web/app/page.tsx index c28eacda..82e4e192 100644 --- a/src/interface/web/app/page.tsx +++ b/src/interface/web/app/page.tsx @@ -6,7 +6,6 @@ import React, { useEffect, useState } from 'react'; import SuggestionCard from './components/suggestions/suggestionCard'; import SidePanel from './components/sidePanel/chatHistorySidePanel'; -import NavMenu from './components/navMenu/navMenu'; import Loading from './components/loading/loading'; import useSWR from 'swr'; import Image from 'next/image'; @@ -157,8 +156,8 @@ function ChatBodyData(props: ChatBodyDataProps) { } return ( -
-
+
+

{greeting}

@@ -218,7 +217,7 @@ function ChatBodyData(props: ChatBodyDataProps) {
@@ -310,7 +309,6 @@ export default function Home() { />
-
-
+
+
-
- -
- { - isMobileWidth &&
Search
- } -
- - setSearchQuery(e.currentTarget.value)} - onKeyDown={(e) => e.key === 'Enter' && search()} - type="search" - placeholder="Search Documents" /> - -
- { - focusSearchResult && -
- - {focusNote(focusSearchResult)} +
+
+
+
+ + setSearchQuery(e.currentTarget.value)} + onKeyDown={(e) => e.key === 'Enter' && search()} + type="search" + placeholder="Search Documents" /> +
- } - { - !focusSearchResult && searchResults && searchResults.length > 0 && -
- - { - searchResults.map((result, index) => { - return ( - - ); - }) - } - -
- } - { - searchResults == null && - - - - - - - Search across your documents - - - - {exampleQuery} - - - } - { - searchResults && searchResults.length === 0 && - - - - - - - No documents found - - - -
- To use search, upload your docs to your account. -
- -
- Learn More + { + focusSearchResult && +
+ + {focusNote(focusSearchResult)} +
+ } + { + !focusSearchResult && searchResults && searchResults.length > 0 && +
+ + { + searchResults.map((result, index) => { + return ( + + ); + }) + } + +
+ } + { + searchResults == null && + + + + + + + Search across your documents + + + + {exampleQuery} + + + } + { + searchResults && searchResults.length === 0 && + + + + + + + No documents found + + + +
+ To use search, upload your docs to your account.
- -
-
- } + +
+ Learn More +
+ + + + } +
diff --git a/src/interface/web/app/search/search.module.css b/src/interface/web/app/search/search.module.css index b063fde6..f4f24a46 100644 --- a/src/interface/web/app/search/search.module.css +++ b/src/interface/web/app/search/search.module.css @@ -1,12 +1,22 @@ div.searchLayout { display: grid; - grid-template-columns: auto 1fr; + grid-template-columns: 1fr; gap: 1rem; height: 100vh; } +div.sidePanel { + position: fixed; + height: 100%; +} + @media screen and (max-width: 768px) { div.searchLayout { gap: 0; } + + div.sidePanel { + position: relative; + height: 100%; + } } From 0d8cdee60a3329c7d66a842f94975a91ca5d1394 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 17:49:50 +0530 Subject: [PATCH 02/53] Adjust spacing when side panel is opened --- .../web/app/components/sidePanel/chatHistorySidePanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index 00e5e26c..eb2c81ae 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -696,7 +696,7 @@ export default function SidePanel(props: SidePanelProps) { : -
+
From 1509c536f94b1307849105d005cc1be392fbd30b Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 19:06:01 +0530 Subject: [PATCH 03/53] Fix layout/styling of the factchecker app --- .../app/factchecker/factChecker.module.css | 11 + .../factchecker/factCheckerLayout.module.css | 10 - src/interface/web/app/factchecker/layout.tsx | 6 +- src/interface/web/app/factchecker/page.tsx | 254 +++++++++--------- 4 files changed, 144 insertions(+), 137 deletions(-) delete mode 100644 src/interface/web/app/factchecker/factCheckerLayout.module.css diff --git a/src/interface/web/app/factchecker/factChecker.module.css b/src/interface/web/app/factchecker/factChecker.module.css index c504d4d6..9882b2a3 100644 --- a/src/interface/web/app/factchecker/factChecker.module.css +++ b/src/interface/web/app/factchecker/factChecker.module.css @@ -13,6 +13,11 @@ input.factVerification { font-size: large; } +div.factCheckerContainer { + width: 75vw; + margin: auto; +} + input.factVerification:focus { outline: none; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); @@ -123,6 +128,12 @@ div.dot2 { animation-delay: -1.0s; } +@media screen and (max-width: 768px) { + div.factCheckerContainer { + width: 95vw; + } +} + @-webkit-keyframes sk-rotate { 100% { -webkit-transform: rotate(360deg) diff --git a/src/interface/web/app/factchecker/factCheckerLayout.module.css b/src/interface/web/app/factchecker/factCheckerLayout.module.css deleted file mode 100644 index 1664029d..00000000 --- a/src/interface/web/app/factchecker/factCheckerLayout.module.css +++ /dev/null @@ -1,10 +0,0 @@ -.factCheckerLayout { - max-width: 70vw; - margin: auto; -} - -@media screen and (max-width: 700px) { - .factCheckerLayout { - max-width: 90vw; - } -} diff --git a/src/interface/web/app/factchecker/layout.tsx b/src/interface/web/app/factchecker/layout.tsx index 8726b59b..5c4e136e 100644 --- a/src/interface/web/app/factchecker/layout.tsx +++ b/src/interface/web/app/factchecker/layout.tsx @@ -1,7 +1,4 @@ - import type { Metadata } from "next"; -import NavMenu from '../components/navMenu/navMenu'; -import styles from './factCheckerLayout.module.css'; export const metadata: Metadata = { title: "Khoj AI - Fact Checker", @@ -17,8 +14,7 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( -
- +
{children}
); diff --git a/src/interface/web/app/factchecker/page.tsx b/src/interface/web/app/factchecker/page.tsx index bb6e5af2..3d6e4882 100644 --- a/src/interface/web/app/factchecker/page.tsx +++ b/src/interface/web/app/factchecker/page.tsx @@ -19,6 +19,7 @@ import { CardTitle, } from "@/components/ui/card" import Link from 'next/link'; +import SidePanel from '../components/sidePanel/chatHistorySidePanel'; @@ -76,41 +77,41 @@ async function verifyStatement( setIsLoading: (loading: boolean) => void, setInitialResponse: (response: string) => void, setInitialReferences: (references: ResponseWithReferences) => void) { - setIsLoading(true); - // Send a message to the chat server to verify the fact - let verificationMessage = `${verificationPrecursor} ${message}`; - const apiURL = `${chatURL}?q=${encodeURIComponent(verificationMessage)}&client=web&stream=true&conversation_id=${conversationId}`; - try { - const response = await fetch(apiURL); - if (!response.body) throw new Error("No response body found"); + setIsLoading(true); + // Send a message to the chat server to verify the fact + let verificationMessage = `${verificationPrecursor} ${message}`; + const apiURL = `${chatURL}?q=${encodeURIComponent(verificationMessage)}&client=web&stream=true&conversation_id=${conversationId}`; + try { + const response = await fetch(apiURL); + if (!response.body) throw new Error("No response body found"); - const reader = response.body?.getReader(); - let decoder = new TextDecoder(); - let result = ""; + const reader = response.body?.getReader(); + let decoder = new TextDecoder(); + let result = ""; - while (true) { - const { done, value } = await reader.read(); - if (done) break; + while (true) { + const { done, value } = await reader.read(); + if (done) break; - let chunk = decoder.decode(value, { stream: true }); + let chunk = decoder.decode(value, { stream: true }); - if (chunk.includes("### compiled references:")) { - const references = handleCompiledReferences(chunk, result); - if (references.response) { - result = references.response; - setInitialResponse(references.response); - setInitialReferences(references); - } - } else { - result += chunk; - setInitialResponse(result); + if (chunk.includes("### compiled references:")) { + const references = handleCompiledReferences(chunk, result); + if (references.response) { + result = references.response; + setInitialResponse(references.response); + setInitialReferences(references); } + } else { + result += chunk; + setInitialResponse(result); } - } catch (error) { - console.error("Error verifying statement: ", error); - } finally { - setIsLoading(false); } + } catch (error) { + console.error("Error verifying statement: ", error); + } finally { + setIsLoading(false); + } } @@ -145,7 +146,7 @@ function ReferenceVerification(props: ReferenceVerificationProps) { setInitialResponse(props.prefilledResponse); setIsLoading(false); } else { - verifyStatement(verificationStatement, props.conversationId, setIsLoading, setInitialResponse, () => {}); + verifyStatement(verificationStatement, props.conversationId, setIsLoading, setInitialResponse, () => { }); } setIsMobileWidth(window.innerWidth < 768); @@ -454,7 +455,7 @@ export default function FactChecker() { additionalLink={additionalLink} setChildReferencesCallback={setChildReferencesCallback} /> ); - }).filter(Boolean); + }).filter(Boolean); }; const renderSupplementalReferences = (references: SupplementReferences[]) => { @@ -489,102 +490,111 @@ export default function FactChecker() { } return ( -
-

- AI Fact Checker -

-
- This is an experimental AI tool. It may make mistakes. -
- { - initialResponse && initialReferences && childReferences - ? -
- - {} : storeData} /> -
- :
-
- setFactToVerify(e.target.value)} - value={factToVerify} - onKeyDown={(e) => { - if (e.key === "Enter") { - onClickVerify(); - } - }} - onFocus={(e) => e.target.placeholder = ""} - onBlur={(e) => e.target.placeholder = "Enter a falsifiable statement to verify"} /> - -
-

- Try with a particular model. You must be subscribed to configure the model. -

-
- } - - {isLoading &&
+ <> +
+ +
+
+

+ AI Fact Checker +

+
+ This is an experimental AI tool. It may make mistakes. +
+ { + initialResponse && initialReferences && childReferences + ? +
+ + { } : storeData} /> +
+ :
+
+ setFactToVerify(e.target.value)} + value={factToVerify} + onKeyDown={(e) => { + if (e.key === "Enter") { + onClickVerify(); + } + }} + onFocus={(e) => e.target.placeholder = ""} + onBlur={(e) => e.target.placeholder = "Enter a falsifiable statement to verify"} /> + +
+

+ Try with a particular model. You must be subscribed to configure the model. +

+
+ } + + {isLoading &&
} - { - initialResponse && - - - {officialFactToVerify} - - -
- - -
-
- - { - initialReferences && initialReferences.online && Object.keys(initialReferences.online).length > 0 && ( -
+ { + initialResponse && + + + {officialFactToVerify} + + +
+ { - const webpages = onlineData?.webpages || []; - return renderWebpages(webpages); - }) + automationId: "", + by: "AI", + message: initialResponse, + context: [], + created: (new Date()).toISOString(), + onlineContext: {} } -
- )} - -
- } - { - initialReferences && -
-

Supplements

-
- { initialReferences.online !== undefined && - renderReferences(conversationID, initialReferences, officialFactToVerify, loadedFromStorage, childReferences)} + } isMobileWidth={isMobileWidth} /> + +
+ + + { + initialReferences && initialReferences.online && Object.keys(initialReferences.online).length > 0 && ( +
+ { + Object.entries(initialReferences.online).map(([key, onlineData], index) => { + const webpages = onlineData?.webpages || []; + return renderWebpages(webpages); + }) + } +
+ )} +
+ + } + { + initialReferences && +
+

Supplements

+
+ {initialReferences.online !== undefined && + renderReferences(conversationID, initialReferences, officialFactToVerify, loadedFromStorage, childReferences)} +
-
- } -
+ } +
+ ) } From e6014e89bfa9c673630d8f2299facf98e40c7d32 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 19:28:59 +0530 Subject: [PATCH 04/53] Fix navmenu in settings page --- src/interface/web/app/settings/page.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/interface/web/app/settings/page.tsx b/src/interface/web/app/settings/page.tsx index 66bf9634..26bdda69 100644 --- a/src/interface/web/app/settings/page.tsx +++ b/src/interface/web/app/settings/page.tsx @@ -655,7 +655,6 @@ export default function SettingsView() { />
-
}>
From d48a789442aee2ca47f8a442fd90fa36703d01a1 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 19:44:30 +0530 Subject: [PATCH 05/53] Use new nav menu alignment in the settings page --- src/interface/web/app/search/page.tsx | 2 +- src/interface/web/app/settings/page.tsx | 4 ++-- .../web/app/settings/settings.module.css | 22 ++++++++++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/interface/web/app/search/page.tsx b/src/interface/web/app/search/page.tsx index 88d54ca4..61e726ac 100644 --- a/src/interface/web/app/search/page.tsx +++ b/src/interface/web/app/search/page.tsx @@ -222,7 +222,7 @@ export default function Search() {
- + ; return ( -
+
{title} @@ -655,7 +655,7 @@ export default function SettingsView() { />
-
+
}>
diff --git a/src/interface/web/app/settings/settings.module.css b/src/interface/web/app/settings/settings.module.css index 8c5ec535..118dc3b1 100644 --- a/src/interface/web/app/settings/settings.module.css +++ b/src/interface/web/app/settings/settings.module.css @@ -1,6 +1,6 @@ div.page { display: grid; - grid-template-columns: auto 1fr; + grid-template-columns: 1fr; gap: 1rem; height: 100vh; color: hsla(var(--foreground)); @@ -8,15 +8,35 @@ div.page { div.contentBody { display: grid; margin: auto; + margin-left: 20vw; + margin-top: 1rem; } div.phoneInput { padding: 0rem; } +div.sidePanel { + position: fixed; + height: 100%; +} + div.phoneInput input { width: 100%; padding: 0.5rem; border: 1px solid hsla(var(--border)); border-radius: 0.25rem; } + +@media screen and (max-width: 768px) { + + div.sidePanel { + position: relative; + height: 100%; + } + + div.contentBody { + margin-left: 0; + margin-top: 0; + } +} From bbe7491f2f814b60a87519f27b2da198dd2bdafa Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 20:12:18 +0530 Subject: [PATCH 06/53] Prompt to login when authenticated, click on suggestion card - Improve styling for the side panel when not logged in --- .../sidePanel/chatHistorySidePanel.tsx | 4 +--- src/interface/web/app/page.tsx | 22 ++++++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index eb2c81ae..7322c12e 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -742,10 +742,8 @@ export default function SidePanel(props: SidePanelProps) { { !authenticatedData && enabled &&
- + - - {/* Redirect to login page */} diff --git a/src/interface/web/app/page.tsx b/src/interface/web/app/page.tsx index 82e4e192..91c5978d 100644 --- a/src/interface/web/app/page.tsx +++ b/src/interface/web/app/page.tsx @@ -21,6 +21,7 @@ import { ClockCounterClockwise } from '@phosphor-icons/react'; import { AgentData } from './agents/page'; import { Suggestion, suggestionsData } from './components/suggestions/suggestionsData'; +import LoginPrompt from './components/loginPrompt/loginPrompt'; //get today's day const today = new Date(); @@ -68,6 +69,7 @@ function ChatBodyData(props: ChatBodyDataProps) { const [selectedAgent, setSelectedAgent] = useState("khoj"); const [agentIcons, setAgentIcons] = useState([]); const [agents, setAgents] = useState([]); + const [showLoginPrompt, setShowLoginPrompt] = useState(false); const agentsFetcher = () => window.fetch('/api/agents').then(res => res.json()).catch(err => console.log(err)); const { data: agentsData, error } = useSWR('agents', agentsFetcher, { revalidateOnFocus: false }); @@ -157,6 +159,13 @@ function ChatBodyData(props: ChatBodyDataProps) { return (
+ { + showLoginPrompt && ( + + ) + }

{greeting}

@@ -202,7 +211,15 @@ function ChatBodyData(props: ChatBodyDataProps) { {shuffledOptions.map((suggestion, index) => (
fillArea(suggestion.link, suggestion.type, suggestion.description)}> + onClick={(event) => { + if (props.isLoggedIn) { + fillArea(suggestion.link, suggestion.type, suggestion.description); + } else { + event.preventDefault(); + event.stopPropagation(); + setShowLoginPrompt(true); + } + }}> (null); const [isLoading, setLoading] = useState(true); - const [title, setTitle] = useState(''); const [conversationId, setConversationID] = useState(null); const [uploadedFiles, setUploadedFiles] = useState([]); const [isMobileWidth, setIsMobileWidth] = useState(false); @@ -299,7 +315,7 @@ export default function Home() { return (
- {title} + Khoj AI - Your Second Brain
Date: Fri, 2 Aug 2024 17:46:13 +0530 Subject: [PATCH 07/53] Update nav menu styling to include everything in one header - Move the nav menu into the chat history side panel component, so that they both show up on one line - Update all pages to use it with the new formatting - in mobile, present the sidebar button, home button, and profile button evenly centered in the middle --- .../web/app/agents/agents.module.css | 7 +- src/interface/web/app/agents/page.tsx | 5 +- .../app/automations/automations.module.css | 5 + src/interface/web/app/automations/page.tsx | 5 +- src/interface/web/app/chat/page.tsx | 36 +++- .../app/components/navMenu/navMenu.module.css | 4 - .../web/app/components/navMenu/navMenu.tsx | 30 +--- .../sidePanel/chatHistorySidePanel.tsx | 38 ++-- .../components/sidePanel/sidePanel.module.css | 6 +- src/interface/web/app/page.module.css | 16 +- src/interface/web/app/page.tsx | 11 +- src/interface/web/app/search/page.tsx | 167 +++++++++--------- .../web/app/search/search.module.css | 12 +- 13 files changed, 183 insertions(+), 159 deletions(-) diff --git a/src/interface/web/app/agents/agents.module.css b/src/interface/web/app/agents/agents.module.css index 8433a88f..73cbd7a3 100644 --- a/src/interface/web/app/agents/agents.module.css +++ b/src/interface/web/app/agents/agents.module.css @@ -46,7 +46,7 @@ div.agentList { } -@media only screen and (max-width: 700px) { +@media only screen and (max-width: 768px) { div.agentList { width: 100%; padding: 0; @@ -54,4 +54,9 @@ div.agentList { margin-left: auto; grid-template-columns: 1fr; } + + div.sidePanel { + position: relative; + height: 100%; + } } diff --git a/src/interface/web/app/agents/page.tsx b/src/interface/web/app/agents/page.tsx index 5e68a0b9..8a9f955a 100644 --- a/src/interface/web/app/agents/page.tsx +++ b/src/interface/web/app/agents/page.tsx @@ -266,9 +266,6 @@ export default function Agents() { return (
-
- -
{ showLoginPrompt &&
-
+

Agents

diff --git a/src/interface/web/app/automations/automations.module.css b/src/interface/web/app/automations/automations.module.css index 99f094c3..f0c35244 100644 --- a/src/interface/web/app/automations/automations.module.css +++ b/src/interface/web/app/automations/automations.module.css @@ -28,4 +28,9 @@ div.sidePanel { div.pageLayout { max-width: 90vw; } + + div.sidePanel { + position: relative; + height: 100%; + } } diff --git a/src/interface/web/app/automations/page.tsx b/src/interface/web/app/automations/page.tsx index 9416cee7..c933f8fd 100644 --- a/src/interface/web/app/automations/page.tsx +++ b/src/interface/web/app/automations/page.tsx @@ -936,9 +936,6 @@ export default function Automations() { return (
-
- -
-

Automations

+

Automations

{ authenticatedData ? ( diff --git a/src/interface/web/app/chat/page.tsx b/src/interface/web/app/chat/page.tsx index 1768a228..702dc894 100644 --- a/src/interface/web/app/chat/page.tsx +++ b/src/interface/web/app/chat/page.tsx @@ -196,7 +196,7 @@ export default function Chat() { } // Track context used for chat response. References are rendered at the end of the chat - ({context, onlineContext} = processMessageChunk(event, currentMessage, context, onlineContext)); + ({ context, onlineContext } = processMessageChunk(event, currentMessage, context, onlineContext)); setMessages([...messages]); } @@ -231,16 +231,34 @@ export default function Chat() { {title} -
- -
+ { + !isMobileWidth && +
+ +
+ }
- + { + isMobileWidth && +
+ +
+ }
+ { + !isMobileWidth && +
+ {title &&

{title}

} +
+ } }> (props.title); - const [isMobileWidth, setIsMobileWidth] = useState(false); const [darkMode, setDarkMode] = useState(false); const [initialLoadDone, setInitialLoadDone] = useState(false); useEffect(() => { setIsMobileWidth(window.innerWidth < 768); - if (props.title) { - setDisplayTitle(props.title); - } else if (!props.title) { - setDisplayTitle(undefined); - } - - }, [props.title]); - - useEffect(() => { window.addEventListener('resize', () => { setIsMobileWidth(window.innerWidth < 768); @@ -94,15 +75,6 @@ export default function NavMenu(props: NavMenuProps) { return (
-
- {displayTitle &&

{displayTitle}

} - { - !displayTitle && props.showLogo && - - - - } -
{ isMobileWidth ? diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index b02ea754..00e5e26c 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -76,6 +76,7 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, import { modifyFileFilterForConversation } from "@/app/common/chatFunctions"; import { ScrollAreaScrollbar } from "@radix-ui/react-scroll-area"; import { KhojLogo, KhojLogoType } from "@/app/components/logo/khogLogo"; +import NavMenu from "../navMenu/navMenu"; // Define a fetcher function const fetcher = (url: string) => fetch(url).then((res) => res.json()); @@ -660,11 +661,8 @@ export default function SidePanel(props: SidePanelProps) { }, [chatSessions]); return ( -
+
- - {props.isMobileWidth && || } - { authenticatedData && props.isMobileWidth ? { @@ -672,7 +670,7 @@ export default function SidePanel(props: SidePanelProps) { setEnabled(open); } }> - + Sessions and Files @@ -698,15 +696,33 @@ export default function SidePanel(props: SidePanelProps) { : -
- - {enabled ? : } +
+ + - +
+ + {enabled ? : } + + +
+
+ +
} + { + props.isMobileWidth && + + + + } + { + props.isMobileWidth && + + }
{ authenticatedData && !props.isMobileWidth && enabled && diff --git a/src/interface/web/app/components/sidePanel/sidePanel.module.css b/src/interface/web/app/components/sidePanel/sidePanel.module.css index 77fddd13..e984eb6a 100644 --- a/src/interface/web/app/components/sidePanel/sidePanel.module.css +++ b/src/interface/web/app/components/sidePanel/sidePanel.module.css @@ -123,9 +123,9 @@ div.modalSessionsList div.session { @media screen and (max-width: 768px) { div.panel { - padding: 0.5rem; - position: fixed; - width: fit-content; + padding: 0.25rem; + /* position: fixed; */ + width: 100%; } div.expanded { diff --git a/src/interface/web/app/page.module.css b/src/interface/web/app/page.module.css index 32c89473..0f02c77a 100644 --- a/src/interface/web/app/page.module.css +++ b/src/interface/web/app/page.module.css @@ -78,7 +78,13 @@ div.chatBoxBody { display: grid; height: 100%; margin: auto; - grid-template-rows: auto 1fr; +} + +div.homeGreetings { + display: grid; + height: 100%; + margin: auto; + grid-template-rows: 1fr 2fr; } @@ -108,6 +114,10 @@ div.sidePanel { grid-template-rows: auto; } + div.sidePanel { + position: relative; + } + div.chatBox { padding: 0; } @@ -117,4 +127,8 @@ div.sidePanel { grid-template-columns: 1fr; } + div.homeGreetings { + grid-template-rows: auto; + } + } diff --git a/src/interface/web/app/page.tsx b/src/interface/web/app/page.tsx index aef9f58c..f8d0fe6d 100644 --- a/src/interface/web/app/page.tsx +++ b/src/interface/web/app/page.tsx @@ -3,7 +3,7 @@ import './globals.css'; import styles from './page.module.css'; import 'katex/dist/katex.min.css'; -import React, { use, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import useSWR from 'swr'; import Image from 'next/image'; import { ClockCounterClockwise } from '@phosphor-icons/react'; @@ -11,7 +11,6 @@ import { ClockCounterClockwise } from '@phosphor-icons/react'; import { Card, CardTitle } from '@/components/ui/card'; import SuggestionCard from '@/app/components/suggestions/suggestionCard'; import SidePanel from '@/app/components/sidePanel/chatHistorySidePanel'; -import NavMenu from '@/app/components/navMenu/navMenu'; import Loading from '@/app/components/loading/loading'; import ChatInputArea, { ChatOptions } from '@/app/components/chatInputArea/chatInputArea'; import { Suggestion, suggestionsData } from '@/app/components/suggestions/suggestionsData'; @@ -22,7 +21,6 @@ import { getIconFromIconName } from '@/app/common/iconUtils'; import { AgentData } from '@/app/agents/page'; - interface ChatBodyDataProps { chatOptionsData: ChatOptions | null; onConversationIdChange?: (conversationId: string) => void; @@ -164,8 +162,8 @@ function ChatBodyData(props: ChatBodyDataProps) { } return ( -
-
+
+

{greeting}

@@ -225,7 +223,7 @@ function ChatBodyData(props: ChatBodyDataProps) {
@@ -324,7 +322,6 @@ export default function Home() { />
-
-
+
+
-
- -
- { - isMobileWidth &&
Search
- } -
- - setSearchQuery(e.currentTarget.value)} - onKeyDown={(e) => e.key === 'Enter' && search()} - type="search" - placeholder="Search Documents" /> - -
- { - focusSearchResult && -
- - {focusNote(focusSearchResult)} +
+
+
+
+ + setSearchQuery(e.currentTarget.value)} + onKeyDown={(e) => e.key === 'Enter' && search()} + type="search" + placeholder="Search Documents" /> +
- } - { - !focusSearchResult && searchResults && searchResults.length > 0 && -
- - { - searchResults.map((result, index) => { - return ( - - ); - }) - } - -
- } - { - searchResults == null && - - - - - - - Search across your documents - - - - {exampleQuery} - - - } - { - searchResults && searchResults.length === 0 && - - - - - - - No documents found - - - -
- To use search, upload your docs to your account. -
- -
- Learn More + { + focusSearchResult && +
+ + {focusNote(focusSearchResult)} +
+ } + { + !focusSearchResult && searchResults && searchResults.length > 0 && +
+ + { + searchResults.map((result, index) => { + return ( + + ); + }) + } + +
+ } + { + searchResults == null && + + + + + + + Search across your documents + + + + {exampleQuery} + + + } + { + searchResults && searchResults.length === 0 && + + + + + + + No documents found + + + +
+ To use search, upload your docs to your account.
- -
-
- } + +
+ Learn More +
+ + + + } +
diff --git a/src/interface/web/app/search/search.module.css b/src/interface/web/app/search/search.module.css index b063fde6..f4f24a46 100644 --- a/src/interface/web/app/search/search.module.css +++ b/src/interface/web/app/search/search.module.css @@ -1,12 +1,22 @@ div.searchLayout { display: grid; - grid-template-columns: auto 1fr; + grid-template-columns: 1fr; gap: 1rem; height: 100vh; } +div.sidePanel { + position: fixed; + height: 100%; +} + @media screen and (max-width: 768px) { div.searchLayout { gap: 0; } + + div.sidePanel { + position: relative; + height: 100%; + } } From 1bb746aaed7c94f98a941b4e6fd0e3207e7daca2 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 17:49:50 +0530 Subject: [PATCH 08/53] Adjust spacing when side panel is opened --- .../web/app/components/sidePanel/chatHistorySidePanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index 00e5e26c..eb2c81ae 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -696,7 +696,7 @@ export default function SidePanel(props: SidePanelProps) { : -
+
From 5f8b76c8f2b86e6d1b467c773aa5006782c06382 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 19:06:01 +0530 Subject: [PATCH 09/53] Fix layout/styling of the factchecker app --- .../app/factchecker/factChecker.module.css | 11 + .../factchecker/factCheckerLayout.module.css | 10 - src/interface/web/app/factchecker/layout.tsx | 6 +- src/interface/web/app/factchecker/page.tsx | 254 +++++++++--------- 4 files changed, 144 insertions(+), 137 deletions(-) delete mode 100644 src/interface/web/app/factchecker/factCheckerLayout.module.css diff --git a/src/interface/web/app/factchecker/factChecker.module.css b/src/interface/web/app/factchecker/factChecker.module.css index c504d4d6..9882b2a3 100644 --- a/src/interface/web/app/factchecker/factChecker.module.css +++ b/src/interface/web/app/factchecker/factChecker.module.css @@ -13,6 +13,11 @@ input.factVerification { font-size: large; } +div.factCheckerContainer { + width: 75vw; + margin: auto; +} + input.factVerification:focus { outline: none; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); @@ -123,6 +128,12 @@ div.dot2 { animation-delay: -1.0s; } +@media screen and (max-width: 768px) { + div.factCheckerContainer { + width: 95vw; + } +} + @-webkit-keyframes sk-rotate { 100% { -webkit-transform: rotate(360deg) diff --git a/src/interface/web/app/factchecker/factCheckerLayout.module.css b/src/interface/web/app/factchecker/factCheckerLayout.module.css deleted file mode 100644 index 1664029d..00000000 --- a/src/interface/web/app/factchecker/factCheckerLayout.module.css +++ /dev/null @@ -1,10 +0,0 @@ -.factCheckerLayout { - max-width: 70vw; - margin: auto; -} - -@media screen and (max-width: 700px) { - .factCheckerLayout { - max-width: 90vw; - } -} diff --git a/src/interface/web/app/factchecker/layout.tsx b/src/interface/web/app/factchecker/layout.tsx index 8726b59b..5c4e136e 100644 --- a/src/interface/web/app/factchecker/layout.tsx +++ b/src/interface/web/app/factchecker/layout.tsx @@ -1,7 +1,4 @@ - import type { Metadata } from "next"; -import NavMenu from '../components/navMenu/navMenu'; -import styles from './factCheckerLayout.module.css'; export const metadata: Metadata = { title: "Khoj AI - Fact Checker", @@ -17,8 +14,7 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( -
- +
{children}
); diff --git a/src/interface/web/app/factchecker/page.tsx b/src/interface/web/app/factchecker/page.tsx index bb6e5af2..3d6e4882 100644 --- a/src/interface/web/app/factchecker/page.tsx +++ b/src/interface/web/app/factchecker/page.tsx @@ -19,6 +19,7 @@ import { CardTitle, } from "@/components/ui/card" import Link from 'next/link'; +import SidePanel from '../components/sidePanel/chatHistorySidePanel'; @@ -76,41 +77,41 @@ async function verifyStatement( setIsLoading: (loading: boolean) => void, setInitialResponse: (response: string) => void, setInitialReferences: (references: ResponseWithReferences) => void) { - setIsLoading(true); - // Send a message to the chat server to verify the fact - let verificationMessage = `${verificationPrecursor} ${message}`; - const apiURL = `${chatURL}?q=${encodeURIComponent(verificationMessage)}&client=web&stream=true&conversation_id=${conversationId}`; - try { - const response = await fetch(apiURL); - if (!response.body) throw new Error("No response body found"); + setIsLoading(true); + // Send a message to the chat server to verify the fact + let verificationMessage = `${verificationPrecursor} ${message}`; + const apiURL = `${chatURL}?q=${encodeURIComponent(verificationMessage)}&client=web&stream=true&conversation_id=${conversationId}`; + try { + const response = await fetch(apiURL); + if (!response.body) throw new Error("No response body found"); - const reader = response.body?.getReader(); - let decoder = new TextDecoder(); - let result = ""; + const reader = response.body?.getReader(); + let decoder = new TextDecoder(); + let result = ""; - while (true) { - const { done, value } = await reader.read(); - if (done) break; + while (true) { + const { done, value } = await reader.read(); + if (done) break; - let chunk = decoder.decode(value, { stream: true }); + let chunk = decoder.decode(value, { stream: true }); - if (chunk.includes("### compiled references:")) { - const references = handleCompiledReferences(chunk, result); - if (references.response) { - result = references.response; - setInitialResponse(references.response); - setInitialReferences(references); - } - } else { - result += chunk; - setInitialResponse(result); + if (chunk.includes("### compiled references:")) { + const references = handleCompiledReferences(chunk, result); + if (references.response) { + result = references.response; + setInitialResponse(references.response); + setInitialReferences(references); } + } else { + result += chunk; + setInitialResponse(result); } - } catch (error) { - console.error("Error verifying statement: ", error); - } finally { - setIsLoading(false); } + } catch (error) { + console.error("Error verifying statement: ", error); + } finally { + setIsLoading(false); + } } @@ -145,7 +146,7 @@ function ReferenceVerification(props: ReferenceVerificationProps) { setInitialResponse(props.prefilledResponse); setIsLoading(false); } else { - verifyStatement(verificationStatement, props.conversationId, setIsLoading, setInitialResponse, () => {}); + verifyStatement(verificationStatement, props.conversationId, setIsLoading, setInitialResponse, () => { }); } setIsMobileWidth(window.innerWidth < 768); @@ -454,7 +455,7 @@ export default function FactChecker() { additionalLink={additionalLink} setChildReferencesCallback={setChildReferencesCallback} /> ); - }).filter(Boolean); + }).filter(Boolean); }; const renderSupplementalReferences = (references: SupplementReferences[]) => { @@ -489,102 +490,111 @@ export default function FactChecker() { } return ( -
-

- AI Fact Checker -

-
- This is an experimental AI tool. It may make mistakes. -
- { - initialResponse && initialReferences && childReferences - ? -
- - {} : storeData} /> -
- :
-
- setFactToVerify(e.target.value)} - value={factToVerify} - onKeyDown={(e) => { - if (e.key === "Enter") { - onClickVerify(); - } - }} - onFocus={(e) => e.target.placeholder = ""} - onBlur={(e) => e.target.placeholder = "Enter a falsifiable statement to verify"} /> - -
-

- Try with a particular model. You must be subscribed to configure the model. -

-
- } - - {isLoading &&
+ <> +
+ +
+
+

+ AI Fact Checker +

+
+ This is an experimental AI tool. It may make mistakes. +
+ { + initialResponse && initialReferences && childReferences + ? +
+ + { } : storeData} /> +
+ :
+
+ setFactToVerify(e.target.value)} + value={factToVerify} + onKeyDown={(e) => { + if (e.key === "Enter") { + onClickVerify(); + } + }} + onFocus={(e) => e.target.placeholder = ""} + onBlur={(e) => e.target.placeholder = "Enter a falsifiable statement to verify"} /> + +
+

+ Try with a particular model. You must be subscribed to configure the model. +

+
+ } + + {isLoading &&
} - { - initialResponse && - - - {officialFactToVerify} - - -
- - -
-
- - { - initialReferences && initialReferences.online && Object.keys(initialReferences.online).length > 0 && ( -
+ { + initialResponse && + + + {officialFactToVerify} + + +
+ { - const webpages = onlineData?.webpages || []; - return renderWebpages(webpages); - }) + automationId: "", + by: "AI", + message: initialResponse, + context: [], + created: (new Date()).toISOString(), + onlineContext: {} } -
- )} - -
- } - { - initialReferences && -
-

Supplements

-
- { initialReferences.online !== undefined && - renderReferences(conversationID, initialReferences, officialFactToVerify, loadedFromStorage, childReferences)} + } isMobileWidth={isMobileWidth} /> + +
+ + + { + initialReferences && initialReferences.online && Object.keys(initialReferences.online).length > 0 && ( +
+ { + Object.entries(initialReferences.online).map(([key, onlineData], index) => { + const webpages = onlineData?.webpages || []; + return renderWebpages(webpages); + }) + } +
+ )} +
+ + } + { + initialReferences && +
+

Supplements

+
+ {initialReferences.online !== undefined && + renderReferences(conversationID, initialReferences, officialFactToVerify, loadedFromStorage, childReferences)} +
-
- } -
+ } +
+ ) } From b1d3979ed9afc3f2bb77de2113fac843927220e7 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 19:28:59 +0530 Subject: [PATCH 10/53] Fix navmenu in settings, share/chat pages --- src/interface/web/app/settings/page.tsx | 1 - src/interface/web/app/share/chat/page.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/interface/web/app/settings/page.tsx b/src/interface/web/app/settings/page.tsx index 59d28b6b..d9320703 100644 --- a/src/interface/web/app/settings/page.tsx +++ b/src/interface/web/app/settings/page.tsx @@ -655,7 +655,6 @@ export default function SettingsView() { />
-
}>
diff --git a/src/interface/web/app/share/chat/page.tsx b/src/interface/web/app/share/chat/page.tsx index c763248b..cd3c4eb7 100644 --- a/src/interface/web/app/share/chat/page.tsx +++ b/src/interface/web/app/share/chat/page.tsx @@ -280,7 +280,6 @@ export default function SharedChat() {
-
}> Date: Fri, 2 Aug 2024 19:44:30 +0530 Subject: [PATCH 11/53] Use new nav menu alignment in the settings page --- src/interface/web/app/search/page.tsx | 2 +- src/interface/web/app/settings/page.tsx | 4 ++-- .../web/app/settings/settings.module.css | 22 ++++++++++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/interface/web/app/search/page.tsx b/src/interface/web/app/search/page.tsx index 88d54ca4..61e726ac 100644 --- a/src/interface/web/app/search/page.tsx +++ b/src/interface/web/app/search/page.tsx @@ -222,7 +222,7 @@ export default function Search() {
- + ; return ( -
+
{title} @@ -655,7 +655,7 @@ export default function SettingsView() { />
-
+
}>
diff --git a/src/interface/web/app/settings/settings.module.css b/src/interface/web/app/settings/settings.module.css index 8c5ec535..118dc3b1 100644 --- a/src/interface/web/app/settings/settings.module.css +++ b/src/interface/web/app/settings/settings.module.css @@ -1,6 +1,6 @@ div.page { display: grid; - grid-template-columns: auto 1fr; + grid-template-columns: 1fr; gap: 1rem; height: 100vh; color: hsla(var(--foreground)); @@ -8,15 +8,35 @@ div.page { div.contentBody { display: grid; margin: auto; + margin-left: 20vw; + margin-top: 1rem; } div.phoneInput { padding: 0rem; } +div.sidePanel { + position: fixed; + height: 100%; +} + div.phoneInput input { width: 100%; padding: 0.5rem; border: 1px solid hsla(var(--border)); border-radius: 0.25rem; } + +@media screen and (max-width: 768px) { + + div.sidePanel { + position: relative; + height: 100%; + } + + div.contentBody { + margin-left: 0; + margin-top: 0; + } +} From f18839639546e681f667bfbf7e27a56179a9a08c Mon Sep 17 00:00:00 2001 From: sabaimran Date: Fri, 2 Aug 2024 20:12:18 +0530 Subject: [PATCH 12/53] Prompt to login when authenticated, click on suggestion card - Improve styling for the side panel when not logged in --- .../sidePanel/chatHistorySidePanel.tsx | 4 +--- src/interface/web/app/page.tsx | 22 ++++++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index eb2c81ae..7322c12e 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -742,10 +742,8 @@ export default function SidePanel(props: SidePanelProps) { { !authenticatedData && enabled &&
- + - - {/* Redirect to login page */} diff --git a/src/interface/web/app/page.tsx b/src/interface/web/app/page.tsx index f8d0fe6d..50701efd 100644 --- a/src/interface/web/app/page.tsx +++ b/src/interface/web/app/page.tsx @@ -14,6 +14,7 @@ import SidePanel from '@/app/components/sidePanel/chatHistorySidePanel'; import Loading from '@/app/components/loading/loading'; import ChatInputArea, { ChatOptions } from '@/app/components/chatInputArea/chatInputArea'; import { Suggestion, suggestionsData } from '@/app/components/suggestions/suggestionsData'; +import LoginPrompt from '@/app/components/loginPrompt/loginPrompt'; import { useAuthenticatedData, UserConfig, useUserConfig } from '@/app/common/auth'; import { convertColorToBorderClass } from '@/app/common/colorUtils'; @@ -53,6 +54,7 @@ function ChatBodyData(props: ChatBodyDataProps) { const [selectedAgent, setSelectedAgent] = useState("khoj"); const [agentIcons, setAgentIcons] = useState([]); const [agents, setAgents] = useState([]); + const [showLoginPrompt, setShowLoginPrompt] = useState(false); const agentsFetcher = () => window.fetch('/api/agents').then(res => res.json()).catch(err => console.log(err)); const { data: agentsData, error } = useSWR('agents', agentsFetcher, { revalidateOnFocus: false }); @@ -163,6 +165,13 @@ function ChatBodyData(props: ChatBodyDataProps) { return (
+ { + showLoginPrompt && ( + + ) + }

{greeting}

@@ -208,7 +217,15 @@ function ChatBodyData(props: ChatBodyDataProps) { {shuffledOptions.map((suggestion, index) => (
fillArea(suggestion.link, suggestion.type, suggestion.description)}> + onClick={(event) => { + if (props.isLoggedIn) { + fillArea(suggestion.link, suggestion.type, suggestion.description); + } else { + event.preventDefault(); + event.stopPropagation(); + setShowLoginPrompt(true); + } + }}> (null); const [isLoading, setLoading] = useState(true); - const [title, setTitle] = useState(''); const [conversationId, setConversationID] = useState(null); const [uploadedFiles, setUploadedFiles] = useState([]); const [isMobileWidth, setIsMobileWidth] = useState(false); @@ -312,7 +328,7 @@ export default function Home() { return (
- {title} + Khoj AI - Your Second Brain
Date: Sat, 3 Aug 2024 04:00:36 +0530 Subject: [PATCH 13/53] Improve alignment of title bar elements --- src/interface/web/app/components/logo/khogLogo.tsx | 2 +- .../web/app/components/sidePanel/chatHistorySidePanel.tsx | 8 ++++---- .../web/app/components/sidePanel/sidePanel.module.css | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/interface/web/app/components/logo/khogLogo.tsx b/src/interface/web/app/components/logo/khogLogo.tsx index c2cdc8c1..fcdeb60c 100644 --- a/src/interface/web/app/components/logo/khogLogo.tsx +++ b/src/interface/web/app/components/logo/khogLogo.tsx @@ -1,6 +1,6 @@ export function KhojLogoType() { return ( - + diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index 7322c12e..f21c6056 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -696,19 +696,19 @@ export default function SidePanel(props: SidePanelProps) { : -
+
-
- +
+ {enabled ? : }
-
+
diff --git a/src/interface/web/app/components/sidePanel/sidePanel.module.css b/src/interface/web/app/components/sidePanel/sidePanel.module.css index e984eb6a..74d5358e 100644 --- a/src/interface/web/app/components/sidePanel/sidePanel.module.css +++ b/src/interface/web/app/components/sidePanel/sidePanel.module.css @@ -143,7 +143,8 @@ div.modalSessionsList div.session { div.session.compressed { max-width: 100%; - grid-template-columns: minmax(auto, 300px) 1fr; + display: flex; + justify-content: space-between; } div.session { From a6e1b2c7cbe6f46d8b86482af0bce8865d68368c Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Sat, 3 Aug 2024 04:12:05 +0530 Subject: [PATCH 14/53] Style nav menu button and expand nav menu item click area to full-width Style profile pircture button on nav menu - Use primary colored ring around subscribed user profile on nav menu - Use gray colored ring around non-subscribed user profile on nav menu - Use upper case initial as profile pic for user with no profile pic - Click anywhere on nav menu item to trigger action Previously the actual clickable area was smaller than the width of the nav menu item --- .../web/app/components/navMenu/navMenu.tsx | 56 ++++++++----------- .../components/suggestions/suggestionCard.tsx | 2 +- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/src/interface/web/app/components/navMenu/navMenu.tsx b/src/interface/web/app/components/navMenu/navMenu.tsx index 859b01a8..c119596a 100644 --- a/src/interface/web/app/components/navMenu/navMenu.tsx +++ b/src/interface/web/app/components/navMenu/navMenu.tsx @@ -81,30 +81,26 @@ export default function NavMenu() { { userData ? - + - - {userData?.username[0]} + + {userData?.username[0].toUpperCase()} : - + } - + setDarkMode(!darkMode)} className='w-full cursor-pointer'>
{ - setDarkMode(!darkMode) - } - } className="flex flex-rows"> {darkMode ? : }

{darkMode ? 'Light Mode' : 'Dark Mode'}

- +

Agents

@@ -112,7 +108,7 @@ export default function NavMenu() { - +

Automations

@@ -120,7 +116,7 @@ export default function NavMenu() { - +

Search

@@ -131,7 +127,7 @@ export default function NavMenu() { {userData && - +

Settings

@@ -140,7 +136,7 @@ export default function NavMenu() { } - +

Help

@@ -150,7 +146,7 @@ export default function NavMenu() { { userData ? - +

Logout

@@ -159,7 +155,7 @@ export default function NavMenu() { : - +

Login

@@ -171,15 +167,15 @@ export default function NavMenu() { : - + { userData ? - + - - {userData?.username[0]} + + {userData?.username[0].toUpperCase()} : @@ -187,19 +183,15 @@ export default function NavMenu() { } - + setDarkMode(!darkMode)} className="w-full hover:cursor-pointer">
{ - setDarkMode(!darkMode) - } - } className="flex flex-rows"> {darkMode ? : }

{darkMode ? 'Light Mode' : 'Dark Mode'}

- +

Agents

@@ -207,7 +199,7 @@ export default function NavMenu() { - +

Automations

@@ -215,7 +207,7 @@ export default function NavMenu() { - +

Search

@@ -225,7 +217,7 @@ export default function NavMenu() { <> - +

Help

@@ -235,7 +227,7 @@ export default function NavMenu() { { userData && - +

Settings

@@ -246,7 +238,7 @@ export default function NavMenu() { { userData ? - +

Logout

@@ -255,7 +247,7 @@ export default function NavMenu() { : - +

Login

diff --git a/src/interface/web/app/components/suggestions/suggestionCard.tsx b/src/interface/web/app/components/suggestions/suggestionCard.tsx index b2b90ac3..8d58c803 100644 --- a/src/interface/web/app/components/suggestions/suggestionCard.tsx +++ b/src/interface/web/app/components/suggestions/suggestionCard.tsx @@ -38,7 +38,7 @@ interface SuggestionCardProps { export default function SuggestionCard(data: SuggestionCardProps) { const bgColors = converColorToBgGradient(data.color); - const cardClassName = `${styles.card} ${bgColors} md:w-full md:h-fit sm:w-full sm:h-fit lg:w-[200px] lg:h-[200px]`; + const cardClassName = `${styles.card} ${bgColors} md:w-full md:h-fit sm:w-full sm:h-fit lg:w-[200px] lg:h-[200px] cursor-pointer`; const titleClassName = `${styles.title} pt-2 dark:text-white dark:font-bold`; const descriptionClassName = `${styles.text} dark:text-white`; From f3765a20b996f71654bdcc0173c248464653decd Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Sat, 3 Aug 2024 07:05:15 +0530 Subject: [PATCH 15/53] Improve content alignment on automation page for small screens - Left align email, location, timezone pills on small screens - Indent user enabled automations to improve delineation between sections --- src/interface/web/app/automations/page.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/interface/web/app/automations/page.tsx b/src/interface/web/app/automations/page.tsx index c933f8fd..251c3500 100644 --- a/src/interface/web/app/automations/page.tsx +++ b/src/interface/web/app/automations/page.tsx @@ -447,7 +447,7 @@ function SharedAutomationCard(props: SharedAutomationCardProps) { - + Create Automation @@ -946,8 +946,8 @@ export default function Automations() {
-

Automations

-
+

Automations

+
{ authenticatedData ? ( {authenticatedData.email} @@ -1035,7 +1035,7 @@ export default function Automations() { { ((!personalAutomations || personalAutomations.length === 0) && (allNewAutomations.length == 0) && !isLoading) && ( -
+
So empty! Create your own automation to get started.
{ From d8fe677933304337e0da586206472799d1299817 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Sat, 3 Aug 2024 07:07:35 +0530 Subject: [PATCH 16/53] Prevent overflow on Search page by search results --- src/interface/web/app/search/page.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/interface/web/app/search/page.tsx b/src/interface/web/app/search/page.tsx index 61e726ac..33b613d8 100644 --- a/src/interface/web/app/search/page.tsx +++ b/src/interface/web/app/search/page.tsx @@ -159,13 +159,7 @@ export default function Search() { }, [isMobileWidth]); function search() { - if (searchResultsLoading) { - return; - } - - if (!searchQuery.trim()) { - return; - } + if (searchResultsLoading || !searchQuery.trim()) return; const apiUrl = `/api/search?q=${encodeURIComponent(searchQuery)}&client=web`; fetch(apiUrl, { @@ -246,7 +240,7 @@ export default function Search() { } { !focusSearchResult && searchResults && searchResults.length > 0 && -
+
{ searchResults.map((result, index) => { From f13621429008c833142d399516b3c7e20f939853 Mon Sep 17 00:00:00 2001 From: sabaimran Date: Sat, 3 Aug 2024 09:44:04 +0530 Subject: [PATCH 17/53] Improve the nav menu in the not logged in experience --- .../sidePanel/chatHistorySidePanel.tsx | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx index f21c6056..2cade4c4 100644 --- a/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx +++ b/src/interface/web/app/components/sidePanel/chatHistorySidePanel.tsx @@ -664,7 +664,7 @@ export default function SidePanel(props: SidePanelProps) {
{ - authenticatedData && props.isMobileWidth ? + props.isMobileWidth ? { if (!enabled) setEnabled(false); setEnabled(open); @@ -676,18 +676,27 @@ export default function SidePanel(props: SidePanelProps) { Sessions and Files View all conversation sessions and manage conversation file filters -
- -
+ { + authenticatedData ? +
+ +
+ : +
+ {/* Redirect to login page */} + + +
+ } @@ -740,7 +749,7 @@ export default function SidePanel(props: SidePanelProps) {
} { - !authenticatedData && enabled && + !authenticatedData && enabled && !props.isMobileWidth &&
From 8d1c5226eca661465514fdc2081e4847318aa05c Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Sat, 3 Aug 2024 07:12:38 +0530 Subject: [PATCH 18/53] Remove unnecessary debug logs --- src/interface/web/app/page.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/interface/web/app/page.tsx b/src/interface/web/app/page.tsx index 50701efd..c81e8576 100644 --- a/src/interface/web/app/page.tsx +++ b/src/interface/web/app/page.tsx @@ -65,12 +65,8 @@ function ChatBodyData(props: ChatBodyDataProps) { } useEffect(() => { - console.log(`Loading user config: ${props.isLoadingUserConfig}`); if (props.isLoadingUserConfig) return; - // Set user config - console.log(`Logged In: ${props.isLoggedIn}\nUserConfig: ${props.userConfig}`); - // Get today's day const today = new Date(); const day = today.getDay(); From 529ffdb7e3ab1fffef0d450cbdc10b48f06814d6 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Sat, 3 Aug 2024 11:22:33 +0530 Subject: [PATCH 19/53] Make Title, Chat Footer Icons larger to ease click, tap on Mobile --- src/interface/web/app/agents/page.tsx | 2 +- src/interface/web/app/chat/chat.module.css | 2 ++ src/interface/web/app/chat/page.tsx | 2 +- .../web/app/components/chatInputArea/chatInputArea.tsx | 9 +++++---- src/interface/web/app/components/logo/khogLogo.tsx | 2 +- src/interface/web/app/components/navMenu/navMenu.tsx | 8 ++++---- .../app/components/sidePanel/chatHistorySidePanel.tsx | 2 +- src/interface/web/app/page.module.css | 4 ++-- src/interface/web/app/page.tsx | 2 +- src/interface/web/app/search/page.tsx | 4 ++-- src/interface/web/app/share/chat/sharedChat.module.css | 2 ++ 11 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/interface/web/app/agents/page.tsx b/src/interface/web/app/agents/page.tsx index 8a9f955a..2d686f5f 100644 --- a/src/interface/web/app/agents/page.tsx +++ b/src/interface/web/app/agents/page.tsx @@ -281,7 +281,7 @@ export default function Agents() { />
-
+

Agents

diff --git a/src/interface/web/app/chat/chat.module.css b/src/interface/web/app/chat/chat.module.css index 311fc036..72b5c675 100644 --- a/src/interface/web/app/chat/chat.module.css +++ b/src/interface/web/app/chat/chat.module.css @@ -105,6 +105,7 @@ div.agentIndicator { div.chatBox { padding: 0; + height: min-content; } } @@ -119,6 +120,7 @@ div.agentIndicator { div.chatBox { padding: 0; + height: min-content; } div.chatLayout { diff --git a/src/interface/web/app/chat/page.tsx b/src/interface/web/app/chat/page.tsx index 702dc894..54487f45 100644 --- a/src/interface/web/app/chat/page.tsx +++ b/src/interface/web/app/chat/page.tsx @@ -256,7 +256,7 @@ export default function Chat() { { !isMobileWidth &&
- {title &&

{title}

} + {title &&

{title}

}
} }> diff --git a/src/interface/web/app/components/chatInputArea/chatInputArea.tsx b/src/interface/web/app/components/chatInputArea/chatInputArea.tsx index 0f8f498b..089bc27f 100644 --- a/src/interface/web/app/components/chatInputArea/chatInputArea.tsx +++ b/src/interface/web/app/components/chatInputArea/chatInputArea.tsx @@ -372,7 +372,7 @@ export default function ChatInputArea(props: ChatInputProps) { className="!bg-none p-1 h-auto text-3xl rounded-full text-gray-300 hover:text-gray-500" disabled={props.sendDisabled} onClick={handleFileButtonClick}> - +