Add mobile stylings to UI (#75)
* initial chat pages mobile stylings * fix sidebar * manage workspace modal styles * mobile styles v1
This commit is contained in:
parent
e7ba028497
commit
3945a77290
@ -4,6 +4,8 @@ import NewWorkspaceModal, {
|
|||||||
useNewWorkspaceModal,
|
useNewWorkspaceModal,
|
||||||
} from "../Modals/NewWorkspace";
|
} from "../Modals/NewWorkspace";
|
||||||
import paths from "../../utils/paths";
|
import paths from "../../utils/paths";
|
||||||
|
import { isMobile } from "react-device-detect";
|
||||||
|
import { SidebarMobileHeader } from "../Sidebar";
|
||||||
|
|
||||||
export default function DefaultChatContainer() {
|
export default function DefaultChatContainer() {
|
||||||
const [mockMsgs, setMockMessages] = useState([]);
|
const [mockMsgs, setMockMessages] = useState([]);
|
||||||
@ -21,8 +23,8 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
Welcome to AnythingLLM, AnythingLLM is an open-source AI tool by
|
Welcome to AnythingLLM, AnythingLLM is an open-source AI tool by
|
||||||
Mintplex Labs that turns <i>anything</i> into a trained chatbot you
|
Mintplex Labs that turns <i>anything</i> into a trained chatbot you
|
||||||
can query and chat with. AnythingLLM is a BYOK (bring-your-own-keys)
|
can query and chat with. AnythingLLM is a BYOK (bring-your-own-keys)
|
||||||
@ -39,8 +41,8 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
AnythingLLM is the easiest way to put powerful AI products like
|
AnythingLLM is the easiest way to put powerful AI products like
|
||||||
OpenAi, GPT-4, LangChain, PineconeDB, ChromaDB, and other services
|
OpenAi, GPT-4, LangChain, PineconeDB, ChromaDB, and other services
|
||||||
together in a neat package with no fuss to increase your
|
together in a neat package with no fuss to increase your
|
||||||
@ -56,8 +58,8 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
AnythingLLM can run totally locally on your machine with little
|
AnythingLLM can run totally locally on your machine with little
|
||||||
overhead you wont even notice it's there! No GPU needed. Cloud and
|
overhead you wont even notice it's there! No GPU needed. Cloud and
|
||||||
on-premises installation is available as well.
|
on-premises installation is available as well.
|
||||||
@ -71,7 +73,7 @@ export default function DefaultChatContainer() {
|
|||||||
className="mt-4 w-fit flex flex-grow gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900 dark:bg-stone-900"
|
className="mt-4 w-fit flex flex-grow gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900 dark:bg-stone-900"
|
||||||
>
|
>
|
||||||
<GitMerge className="h-4 w-4" />
|
<GitMerge className="h-4 w-4" />
|
||||||
<p className="text-slate-800 dark:text-slate-200 text-lg leading-loose">
|
<p className="text-slate-800 dark:text-slate-200 text-sm md:text-lg leading-loose">
|
||||||
Create an issue on Github
|
Create an issue on Github
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
@ -85,8 +87,8 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-slate-200 dark:bg-amber-800 rounded-b-2xl rounded-tl-2xl rounded-tr-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-slate-200 dark:bg-amber-800 rounded-b-2xl rounded-tl-2xl rounded-tr-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
How do I get started?!
|
How do I get started?!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -99,8 +101,8 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
It's simple. All collections are organized into buckets we call{" "}
|
It's simple. All collections are organized into buckets we call{" "}
|
||||||
<b>"Workspaces"</b>. Workspaces are buckets of files, documents,
|
<b>"Workspaces"</b>. Workspaces are buckets of files, documents,
|
||||||
images, PDFs, and other files which will be transformed into
|
images, PDFs, and other files which will be transformed into
|
||||||
@ -114,7 +116,7 @@ export default function DefaultChatContainer() {
|
|||||||
className="mt-4 w-fit flex flex-grow gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900 dark:bg-stone-900"
|
className="mt-4 w-fit flex flex-grow gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900 dark:bg-stone-900"
|
||||||
>
|
>
|
||||||
<Plus className="h-4 w-4" />
|
<Plus className="h-4 w-4" />
|
||||||
<p className="text-slate-800 dark:text-slate-200 text-lg leading-loose">
|
<p className="text-slate-800 dark:text-slate-200 text-sm md:text-lg leading-loose">
|
||||||
Create your first workspace
|
Create your first workspace
|
||||||
</p>
|
</p>
|
||||||
</button>
|
</button>
|
||||||
@ -128,8 +130,8 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-slate-200 dark:bg-amber-800 rounded-b-2xl rounded-tl-2xl rounded-tr-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-slate-200 dark:bg-amber-800 rounded-b-2xl rounded-tl-2xl rounded-tr-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
Is this like an AI dropbox or something? What about chatting? It is
|
Is this like an AI dropbox or something? What about chatting? It is
|
||||||
a chatbot isn't it?
|
a chatbot isn't it?
|
||||||
</p>
|
</p>
|
||||||
@ -143,8 +145,8 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
AnythingLLM is more than a smarter Dropbox.
|
AnythingLLM is more than a smarter Dropbox.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
@ -174,8 +176,8 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-slate-200 dark:bg-amber-800 rounded-b-2xl rounded-tl-2xl rounded-tr-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-slate-200 dark:bg-amber-800 rounded-b-2xl rounded-tl-2xl rounded-tr-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
Wow, this sounds amazing, let me try it out already!
|
Wow, this sounds amazing, let me try it out already!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -188,18 +190,18 @@ export default function DefaultChatContainer() {
|
|||||||
popMsg ? "chat__message" : ""
|
popMsg ? "chat__message" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="p-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
<div className="p-4 max-w-full md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-b-2xl rounded-tr-2xl rounded-tl-sm">
|
||||||
<p className="text-slate-800 dark:text-slate-200 font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base">
|
||||||
Have Fun!
|
Have Fun!
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-x-4">
|
<div className="flex flex-col md:flex-row items-start md:items-center gap-1 md:gap-4">
|
||||||
<a
|
<a
|
||||||
href={paths.github()}
|
href={paths.github()}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="mt-4 w-fit flex flex-grow gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900 dark:bg-stone-900"
|
className="mt-4 w-fit flex flex-grow gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900 dark:bg-stone-900"
|
||||||
>
|
>
|
||||||
<GitHub className="h-4 w-4" />
|
<GitHub className="h-4 w-4" />
|
||||||
<p className="text-slate-800 dark:text-slate-200 text-lg leading-loose">
|
<p className="text-slate-800 dark:text-slate-200 text-sm md:text-lg leading-loose">
|
||||||
Star on GitHub
|
Star on GitHub
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
@ -208,7 +210,7 @@ export default function DefaultChatContainer() {
|
|||||||
className="mt-4 w-fit flex flex-grow gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900 dark:bg-stone-900"
|
className="mt-4 w-fit flex flex-grow gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900 dark:bg-stone-900"
|
||||||
>
|
>
|
||||||
<Mail className="h-4 w-4" />
|
<Mail className="h-4 w-4" />
|
||||||
<p className="text-slate-800 dark:text-slate-200 text-lg leading-loose">
|
<p className="text-slate-800 dark:text-slate-200 text-sm md:text-lg leading-loose">
|
||||||
Contact Mintplex Labs
|
Contact Mintplex Labs
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
@ -245,9 +247,10 @@ export default function DefaultChatContainer() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{ height: "calc(100% - 32px)" }}
|
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||||
className="transition-all duration-500 relative ml-[2px] mr-[8px] my-[16px] rounded-[26px] bg-white dark:bg-black-900 min-w-[82%] p-[18px] h-full overflow-y-scroll"
|
className="transition-all duration-500 relative md:ml-[2px] md:mr-[8px] md:my-[16px] md:rounded-[26px] bg-white dark:bg-black-900 md:min-w-[82%] p-[18px] h-full overflow-y-scroll"
|
||||||
>
|
>
|
||||||
|
{isMobile && <SidebarMobileHeader />}
|
||||||
{mockMsgs.map((content, i) => {
|
{mockMsgs.map((content, i) => {
|
||||||
return <React.Fragment key={i}>{content}</React.Fragment>;
|
return <React.Fragment key={i}>{content}</React.Fragment>;
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ export default function KeysModal({ hideModal = noop }) {
|
|||||||
<div className="relative bg-white rounded-lg shadow dark:bg-stone-700">
|
<div className="relative bg-white rounded-lg shadow dark:bg-stone-700">
|
||||||
<div className="flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600">
|
<div className="flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600">
|
||||||
<h3 className="text-xl font-semibold text-gray-900 dark:text-white">
|
<h3 className="text-xl font-semibold text-gray-900 dark:text-white">
|
||||||
Your System Settings
|
System Settings
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
onClick={hideModal}
|
onClick={hideModal}
|
||||||
@ -48,7 +48,7 @@ export default function KeysModal({ hideModal = noop }) {
|
|||||||
<div className="w-full flex flex-col gap-y-4">
|
<div className="w-full flex flex-col gap-y-4">
|
||||||
<div className="bg-orange-300 p-4 rounded-lg border border-orange-600 text-orange-700 w-full items-center flex gap-x-2">
|
<div className="bg-orange-300 p-4 rounded-lg border border-orange-600 text-orange-700 w-full items-center flex gap-x-2">
|
||||||
<AlertCircle className="h-8 w-8" />
|
<AlertCircle className="h-8 w-8" />
|
||||||
<p>
|
<p className="text-sm md:text-base ">
|
||||||
Ensure all fields are green before attempting to use
|
Ensure all fields are green before attempting to use
|
||||||
AnythingLLM or it may not function as expected!
|
AnythingLLM or it may not function as expected!
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -42,7 +42,7 @@ export default function Directory({
|
|||||||
className="flex gap-x-2 items-center cursor-pointer w-full"
|
className="flex gap-x-2 items-center cursor-pointer w-full"
|
||||||
onClick={() => toggleExpanded(!isExpanded)}
|
onClick={() => toggleExpanded(!isExpanded)}
|
||||||
>
|
>
|
||||||
<h2 className="text-2xl">{files.name}</h2>
|
<h2 className="text-base md:text-2xl">{files.name}</h2>
|
||||||
{files.items.some((files) => files.type === "folder") ? (
|
{files.items.some((files) => files.type === "folder") ? (
|
||||||
<p className="text-xs italic">{files.items.length} folders</p>
|
<p className="text-xs italic">{files.items.length} folders</p>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@ -197,11 +197,11 @@ export default function DocumentSettings({ workspace }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
|
<div className="flex items-center justify-between p-4 md:p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
|
||||||
<button
|
<button
|
||||||
onClick={deleteWorkspace}
|
onClick={deleteWorkspace}
|
||||||
type="button"
|
type="button"
|
||||||
className="border border-transparent text-gray-500 bg-white hover:bg-red-100 rounded-lg text-sm font-medium px-5 py-2.5 hover:text-red-900 focus:z-10 dark:bg-transparent dark:text-gray-300 dark:hover:text-white dark:hover:bg-red-600"
|
className="border border-transparent text-gray-500 bg-white hover:bg-red-100 rounded-lg whitespace-nowrap text-sm font-medium px-5 py-2.5 hover:text-red-900 focus:z-10 dark:bg-transparent dark:text-gray-300 dark:hover:text-white dark:hover:bg-red-600"
|
||||||
>
|
>
|
||||||
Delete Workspace
|
Delete Workspace
|
||||||
</button>
|
</button>
|
||||||
@ -210,7 +210,7 @@ export default function DocumentSettings({ workspace }) {
|
|||||||
disabled={saving}
|
disabled={saving}
|
||||||
onClick={confirmChanges}
|
onClick={confirmChanges}
|
||||||
type="submit"
|
type="submit"
|
||||||
className="text-slate-200 bg-black-900 px-4 py-2 rounded-lg hover:bg-gray-900"
|
className="text-slate-200 bg-black-900 px-4 py-2 rounded-lg hover:bg-gray-900 whitespace-nowrap text-sm"
|
||||||
>
|
>
|
||||||
{saving ? "Saving..." : "Confirm Changes"}
|
{saving ? "Saving..." : "Confirm Changes"}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -154,18 +154,18 @@ export default function WorkspaceSettings({ workspace }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
|
<div className="flex items-center justify-between p-2 md:p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
|
||||||
<button
|
<button
|
||||||
onClick={deleteWorkspace}
|
onClick={deleteWorkspace}
|
||||||
type="button"
|
type="button"
|
||||||
className="border border-transparent text-gray-500 bg-white hover:bg-red-100 rounded-lg text-sm font-medium px-5 py-2.5 hover:text-red-900 focus:z-10 dark:bg-transparent dark:text-gray-300 dark:hover:text-white dark:hover:bg-red-600"
|
className="border border-transparent text-gray-500 bg-white hover:bg-red-100 rounded-lg whitespace-nowrap text-sm font-medium px-5 py-2.5 hover:text-red-900 focus:z-10 dark:bg-transparent dark:text-gray-300 dark:hover:text-white dark:hover:bg-red-600"
|
||||||
>
|
>
|
||||||
Delete Workspace
|
Delete Workspace
|
||||||
</button>
|
</button>
|
||||||
{hasChanges && (
|
{hasChanges && (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-black dark:text-slate-200 dark:border-transparent dark:hover:text-slate-200 dark:hover:bg-gray-900 dark:focus:ring-gray-800"
|
className="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 whitespace-nowrap text-sm font-medium px-2 md:px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-black dark:text-slate-200 dark:border-transparent dark:hover:text-slate-200 dark:hover:bg-gray-900 dark:focus:ring-gray-800"
|
||||||
>
|
>
|
||||||
{saving ? "Updating..." : "Update workspace"}
|
{saving ? "Updating..." : "Update workspace"}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -78,12 +78,12 @@ export default function UploadToWorkspace({ workspace, fileTypes }) {
|
|||||||
return (
|
return (
|
||||||
<ModalWrapper deleteWorkspace={deleteWorkspace}>
|
<ModalWrapper deleteWorkspace={deleteWorkspace}>
|
||||||
<div className="outline-none transition-all duration-300 bg-red-200 flex h-[20rem] overflow-y-scroll overflow-x-hidden rounded-lg">
|
<div className="outline-none transition-all duration-300 bg-red-200 flex h-[20rem] overflow-y-scroll overflow-x-hidden rounded-lg">
|
||||||
<div className="flex flex-col gap-y-1 w-full h-full items-center justify-center">
|
<div className="flex flex-col gap-y-1 w-full h-full items-center justify-center md:px-0 px-2">
|
||||||
<Frown className="w-8 h-8 text-red-800" />
|
<Frown className="w-8 h-8 text-red-800" />
|
||||||
<p className="text-red-800 text-xs">
|
<p className="text-red-800 text-xs text-center">
|
||||||
Document processor is offline.
|
Document processor is offline.
|
||||||
</p>
|
</p>
|
||||||
<p className="text-red-800 text-xs">
|
<p className="text-red-800 text-[10px] md:text-xs text-center">
|
||||||
you cannot upload documents from the UI right now
|
you cannot upload documents from the UI right now
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -83,26 +83,26 @@ export default function ManageWorkspace({
|
|||||||
function WorkspaceSettingTabs({ selectedTab, changeTab }) {
|
function WorkspaceSettingTabs({ selectedTab, changeTab }) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ul className="flex flex-wrap -mb-px text-sm gap-x-2 font-medium text-center text-gray-500 dark:text-gray-400">
|
<ul className="flex md:flex-wrap overflow-x-scroll no-scroll -mb-px text-sm gap-x-2 font-medium text-center text-gray-500 dark:text-gray-400">
|
||||||
<WorkspaceTab
|
<WorkspaceTab
|
||||||
active={selectedTab === "documents"}
|
active={selectedTab === "documents"}
|
||||||
displayName="Documents"
|
displayName="Documents"
|
||||||
tabName="documents"
|
tabName="documents"
|
||||||
icon={<Archive className="h-4 w-4" />}
|
icon={<Archive className="h-4 w-4 flex-shrink-0" />}
|
||||||
onClick={changeTab}
|
onClick={changeTab}
|
||||||
/>
|
/>
|
||||||
<WorkspaceTab
|
<WorkspaceTab
|
||||||
active={selectedTab === "upload"}
|
active={selectedTab === "upload"}
|
||||||
displayName="Upload Docs"
|
displayName="Upload Docs"
|
||||||
tabName="upload"
|
tabName="upload"
|
||||||
icon={<UploadCloud className="h-4 w-4" />}
|
icon={<UploadCloud className="h-4 w-4 flex-shrink-0" />}
|
||||||
onClick={changeTab}
|
onClick={changeTab}
|
||||||
/>
|
/>
|
||||||
<WorkspaceTab
|
<WorkspaceTab
|
||||||
active={selectedTab === "settings"}
|
active={selectedTab === "settings"}
|
||||||
displayName="Settings"
|
displayName="Settings"
|
||||||
tabName="settings"
|
tabName="settings"
|
||||||
icon={<Sliders className="h-4 w-4" />}
|
icon={<Sliders className="h-4 w-4 flex-shrink-0" />}
|
||||||
onClick={changeTab}
|
onClick={changeTab}
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
@ -126,7 +126,7 @@ function WorkspaceTab({
|
|||||||
disabled={active}
|
disabled={active}
|
||||||
onClick={() => onClick(tabName)}
|
onClick={() => onClick(tabName)}
|
||||||
className={
|
className={
|
||||||
"flex items-center gap-x-1 p-4 border-b-2 rounded-t-lg group " +
|
"flex items-center gap-x-1 p-4 border-b-2 rounded-t-lg group whitespace-nowrap " +
|
||||||
classes
|
classes
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export default function NewWorkspaceModal({ hideModal = noop }) {
|
|||||||
Error: {error}
|
Error: {error}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<p className="text-gray-800 dark:text-slate-200 text-sm">
|
<p className="text-gray-800 dark:text-slate-200 text-xs md:text-sm">
|
||||||
After creating a workspace you will be able to add and remove
|
After creating a workspace you will be able to add and remove
|
||||||
documents from it.
|
documents from it.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -31,7 +31,7 @@ export default function PasswordModal() {
|
|||||||
<form ref={formEl} onSubmit={handleLogin}>
|
<form ref={formEl} onSubmit={handleLogin}>
|
||||||
<div className="relative bg-white rounded-lg shadow dark:bg-stone-700">
|
<div className="relative bg-white rounded-lg shadow dark:bg-stone-700">
|
||||||
<div className="flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600">
|
<div className="flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600">
|
||||||
<h3 className="text-xl font-semibold text-gray-900 dark:text-white">
|
<h3 className="text-md md:text-xl font-semibold text-gray-900 dark:text-white">
|
||||||
This workspace is password protected.
|
This workspace is password protected.
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
@ -58,7 +58,7 @@ export default function PasswordModal() {
|
|||||||
Error: {error}
|
Error: {error}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<p className="text-gray-800 dark:text-slate-200 text-sm">
|
<p className="text-gray-800 dark:text-slate-200 md:text-sm text-xs">
|
||||||
You will only have to enter this password once. After
|
You will only have to enter this password once. After
|
||||||
successful login it will be stored in your browser.
|
successful login it will be stored in your browser.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -57,8 +57,8 @@ export default function ActiveWorkspaces() {
|
|||||||
: "hover:bg-slate-100 dark:hover:bg-stone-900 "
|
: "hover:bg-slate-100 dark:hover:bg-stone-900 "
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Book className="h-4 w-4" />
|
<Book className="h-4 w-4 flex-shrink-0" />
|
||||||
<p className="text-slate-800 dark:text-slate-200 text-xs leading-loose font-semibold">
|
<p className="text-slate-800 dark:text-slate-200 text-xs leading-loose font-semibold whitespace-nowrap overflow-hidden ">
|
||||||
{workspace.name}
|
{workspace.name}
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@ -1,5 +1,13 @@
|
|||||||
import React, { useRef } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { BookOpen, Briefcase, Cpu, GitHub, Key, Plus } from "react-feather";
|
import {
|
||||||
|
BookOpen,
|
||||||
|
Briefcase,
|
||||||
|
Cpu,
|
||||||
|
GitHub,
|
||||||
|
Key,
|
||||||
|
Menu,
|
||||||
|
Plus,
|
||||||
|
} from "react-feather";
|
||||||
import IndexCount from "./IndexCount";
|
import IndexCount from "./IndexCount";
|
||||||
import LLMStatus from "./LLMStatus";
|
import LLMStatus from "./LLMStatus";
|
||||||
import KeysModal, { useKeysModal } from "../Modals/Keys";
|
import KeysModal, { useKeysModal } from "../Modals/Keys";
|
||||||
@ -22,11 +30,6 @@ export default function Sidebar() {
|
|||||||
hideModal: hideNewWsModal,
|
hideModal: hideNewWsModal,
|
||||||
} = useNewWorkspaceModal();
|
} = useNewWorkspaceModal();
|
||||||
|
|
||||||
// const handleWidthToggle = () => {
|
|
||||||
// if (!sidebarRef.current) return false;
|
|
||||||
// sidebarRef.current.classList.add('translate-x-[-100%]')
|
|
||||||
// }
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
@ -34,11 +37,6 @@ export default function Sidebar() {
|
|||||||
style={{ height: "calc(100% - 32px)" }}
|
style={{ height: "calc(100% - 32px)" }}
|
||||||
className="transition-all duration-500 relative m-[16px] rounded-[26px] bg-white dark:bg-black-900 min-w-[15.5%] p-[18px] "
|
className="transition-all duration-500 relative m-[16px] rounded-[26px] bg-white dark:bg-black-900 min-w-[15.5%] p-[18px] "
|
||||||
>
|
>
|
||||||
{/* <button onClick={handleWidthToggle} className='absolute -right-[13px] top-[35%] bg-white w-auto h-auto bg-transparent flex items-center'>
|
|
||||||
<svg width="16" height="96" viewBox="0 0 16 96" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="#141414"><path d="M2.5 0H3C3 20 15 12 15 32V64C15 84 3 76 3 96H2.5V0Z" fill="black" fill-opacity="0.12" stroke="transparent" stroke-width="0px"></path><path d="M0 0H2.5C2.5 20 14.5 12 14.5 32V64C14.5 84 2.5 76 2.5 96H0V0Z" fill="#141414"></path></svg>
|
|
||||||
<ChevronLeft className='absolute h-4 w-4 text-white mr-1' />
|
|
||||||
</button> */}
|
|
||||||
|
|
||||||
<div className="w-full h-full flex flex-col overflow-x-hidden items-between">
|
<div className="w-full h-full flex flex-col overflow-x-hidden items-between">
|
||||||
{/* Header Information */}
|
{/* Header Information */}
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
@ -133,3 +131,161 @@ export default function Sidebar() {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function SidebarMobileHeader() {
|
||||||
|
const [showSidebar, setShowSidebar] = useState(false);
|
||||||
|
const [showBgOverlay, setShowBgOverlay] = useState(false);
|
||||||
|
const sidebarRef = useRef(null);
|
||||||
|
const {
|
||||||
|
showing: showingKeyModal,
|
||||||
|
showModal: showKeyModal,
|
||||||
|
hideModal: hideKeyModal,
|
||||||
|
} = useKeysModal();
|
||||||
|
const {
|
||||||
|
showing: showingNewWsModal,
|
||||||
|
showModal: showNewWsModal,
|
||||||
|
hideModal: hideNewWsModal,
|
||||||
|
} = useNewWorkspaceModal();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function handleBg() {
|
||||||
|
if (showSidebar) {
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowBgOverlay(true);
|
||||||
|
}, 300);
|
||||||
|
} else {
|
||||||
|
setShowBgOverlay(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleBg();
|
||||||
|
}, [showSidebar]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="flex justify-between relative top-0 left-0 w-full rounded-b-lg px-2 pb-4 bg-white dark:bg-black-900 text-slate-800 dark:text-slate-200">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowSidebar(true)}
|
||||||
|
className="rounded-md bg-stone-200 p-2 flex items-center justify-center text-slate-800 hover:bg-stone-300 group dark:bg-stone-800 dark:text-slate-200 dark:hover:bg-stone-900 dark:border dark:border-stone-800"
|
||||||
|
>
|
||||||
|
<Menu className="h-6 w-6" />
|
||||||
|
</button>
|
||||||
|
<p className="text-xl font-base text-slate-600 dark:text-slate-200">
|
||||||
|
AnythingLLM
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
transform: showSidebar ? `translateX(0vw)` : `translateX(-100vw)`,
|
||||||
|
}}
|
||||||
|
className={`z-99 fixed top-0 left-0 transition-all duration-500 w-[100vw] h-[100vh]`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
showBgOverlay
|
||||||
|
? "transition-all opacity-1"
|
||||||
|
: "transition-none opacity-0"
|
||||||
|
} duration-500 fixed top-0 left-0 bg-black-900 bg-opacity-75 w-screen h-screen`}
|
||||||
|
onClick={() => setShowSidebar(false)}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
ref={sidebarRef}
|
||||||
|
className="h-[100vh] fixed top-0 left-0 rounded-r-[26px] bg-white dark:bg-black-900 w-[70%] p-[18px] "
|
||||||
|
>
|
||||||
|
<div className="w-full h-full flex flex-col overflow-x-hidden items-between">
|
||||||
|
{/* Header Information */}
|
||||||
|
<div className="flex w-full items-center justify-between">
|
||||||
|
<p className="text-xl font-base text-slate-600 dark:text-slate-200">
|
||||||
|
AnythingLLM
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-x-2 items-center text-slate-500">
|
||||||
|
<button
|
||||||
|
onClick={showKeyModal}
|
||||||
|
className="transition-all duration-300 p-2 rounded-full bg-slate-200 text-slate-400 dark:bg-stone-800 hover:bg-slate-800 hover:text-slate-200 dark:hover:text-slate-200"
|
||||||
|
>
|
||||||
|
<Key className="h-4 w-4 " />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Primary Body */}
|
||||||
|
<div className="h-full flex flex-col w-full justify-between pt-4 overflow-y-hidden ">
|
||||||
|
<div className="h-auto md:sidebar-items md:dark:sidebar-items">
|
||||||
|
<div
|
||||||
|
style={{ height: "calc(100vw - -3rem)" }}
|
||||||
|
className=" flex flex-col gap-y-4 pb-8 overflow-y-scroll no-scroll"
|
||||||
|
>
|
||||||
|
<div className="flex gap-x-2 items-center justify-between">
|
||||||
|
<button
|
||||||
|
onClick={showNewWsModal}
|
||||||
|
className="flex flex-grow w-[75%] h-[36px] gap-x-2 py-[5px] px-4 border border-slate-400 rounded-lg text-slate-800 dark:text-slate-200 justify-start items-center hover:bg-slate-100 dark:hover:bg-stone-900"
|
||||||
|
>
|
||||||
|
<Plus className="h-4 w-4" />
|
||||||
|
<p className="text-slate-800 dark:text-slate-200 text-xs leading-loose font-semibold">
|
||||||
|
New workspace
|
||||||
|
</p>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<ActiveWorkspaces />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="flex flex-col gap-y-2">
|
||||||
|
<div className="w-full flex items-center justify-between">
|
||||||
|
<LLMStatus />
|
||||||
|
<IndexCount />
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
href={paths.hosting()}
|
||||||
|
target="_blank"
|
||||||
|
className="flex flex-grow w-[100%] h-[36px] gap-x-2 py-[5px] px-4 border border-slate-400 dark:border-transparent rounded-lg text-slate-800 dark:text-slate-200 justify-center items-center hover:bg-slate-100 dark:bg-stone-800 dark:hover:bg-stone-900"
|
||||||
|
>
|
||||||
|
<Cpu className="h-4 w-4" />
|
||||||
|
<p className="text-slate-800 dark:text-slate-200 text-xs leading-loose font-semibold">
|
||||||
|
Managed cloud hosting
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href={paths.hosting()}
|
||||||
|
target="_blank"
|
||||||
|
className="flex flex-grow w-[100%] h-[36px] gap-x-2 py-[5px] px-4 border border-slate-400 dark:border-transparent rounded-lg text-slate-800 dark:text-slate-200 justify-center items-center hover:bg-slate-100 dark:bg-stone-800 dark:hover:bg-stone-900"
|
||||||
|
>
|
||||||
|
<Briefcase className="h-4 w-4" />
|
||||||
|
<p className="text-slate-800 dark:text-slate-200 text-xs leading-loose font-semibold">
|
||||||
|
Enterprise Installation
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Footer */}
|
||||||
|
<div className="flex items-end justify-between mt-2">
|
||||||
|
<div className="flex gap-x-1 items-center">
|
||||||
|
<a
|
||||||
|
href={paths.github()}
|
||||||
|
className="transition-all duration-300 p-2 rounded-full bg-slate-200 text-slate-400 dark:bg-slate-800 hover:bg-slate-800 hover:text-slate-200 dark:hover:text-slate-200"
|
||||||
|
>
|
||||||
|
<GitHub className="h-4 w-4 " />
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href={paths.docs()}
|
||||||
|
className="transition-all duration-300 p-2 rounded-full bg-slate-200 text-slate-400 dark:bg-slate-800 hover:bg-slate-800 hover:text-slate-200 dark:hover:text-slate-200"
|
||||||
|
>
|
||||||
|
<BookOpen className="h-4 w-4 " />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
href={paths.mailToMintplex()}
|
||||||
|
className="transition-all duration-300 text-xs text-slate-200 dark:text-slate-600 hover:text-blue-600 dark:hover:text-blue-400"
|
||||||
|
>
|
||||||
|
@MintplexLabs
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{showingKeyModal && <KeysModal hideModal={hideKeyModal} />}
|
||||||
|
{showingNewWsModal && <NewWorkspaceModal hideModal={hideNewWsModal} />}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -21,9 +21,9 @@ function HistoricalMessage({
|
|||||||
if (role === "user") {
|
if (role === "user") {
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-end mb-4 items-start">
|
<div className="flex justify-end mb-4 items-start">
|
||||||
<div className="mr-2 py-1 px-4 max-w-[75%] bg-slate-200 dark:bg-amber-800 rounded-b-2xl rounded-tl-2xl rounded-tr-sm">
|
<div className="mr-2 py-1 px-4 w-fit md:max-w-[75%] bg-slate-200 dark:bg-amber-800 rounded-b-2xl rounded-tl-2xl rounded-tr-sm">
|
||||||
<span
|
<span
|
||||||
className={`inline-block p-2 rounded-lg whitespace-pre-line text-slate-800 dark:text-slate-200 font-semibold`}
|
className={`inline-block p-2 rounded-lg whitespace-pre-line text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base`}
|
||||||
>
|
>
|
||||||
{message}
|
{message}
|
||||||
</span>
|
</span>
|
||||||
@ -52,9 +52,9 @@ function HistoricalMessage({
|
|||||||
return (
|
return (
|
||||||
<div ref={replyRef} className="flex justify-start items-end mb-4">
|
<div ref={replyRef} className="flex justify-start items-end mb-4">
|
||||||
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
||||||
<div className="ml-2 py-3 px-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
<div className="ml-2 py-3 px-4 overflow-x-scroll w-fit md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
||||||
<span
|
<span
|
||||||
className="whitespace-pre-line text-slate-800 dark:text-slate-200 font-semibold flex flex-col gap-y-1"
|
className="whitespace-pre-line text-slate-800 dark:text-slate-200 font-[500] md:font-semibold text-sm md:text-base flex flex-col gap-y-1"
|
||||||
dangerouslySetInnerHTML={{ __html: renderMarkdown(message) }}
|
dangerouslySetInnerHTML={{ __html: renderMarkdown(message) }}
|
||||||
/>
|
/>
|
||||||
<Citations sources={sources} />
|
<Citations sources={sources} />
|
||||||
|
|||||||
@ -25,7 +25,7 @@ function PromptReply({
|
|||||||
return (
|
return (
|
||||||
<div className="chat__message flex justify-start mb-4 items-end">
|
<div className="chat__message flex justify-start mb-4 items-end">
|
||||||
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
||||||
<div className="ml-2 pt-2 px-6 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
<div className="ml-2 pt-2 px-6 w-fit md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
||||||
<span className={`inline-block p-2`}>
|
<span className={`inline-block p-2`}>
|
||||||
<div className="dot-falling"></div>
|
<div className="dot-falling"></div>
|
||||||
</span>
|
</span>
|
||||||
@ -58,9 +58,9 @@ function PromptReply({
|
|||||||
className="mb-4 flex justify-start items-end"
|
className="mb-4 flex justify-start items-end"
|
||||||
>
|
>
|
||||||
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
||||||
<div className="ml-2 py-3 px-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
<div className="ml-2 py-3 px-4 overflow-x-scroll w-fit md:max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
||||||
<span
|
<span
|
||||||
className="whitespace-pre-line text-slate-800 dark:text-slate-200 font-semibold flex flex-col gap-y-1"
|
className="whitespace-pre-line text-slate-800 dark:text-slate-200 flex flex-col gap-y-1 font-[500] md:font-semibold text-sm md:text-base"
|
||||||
dangerouslySetInnerHTML={{ __html: renderMarkdown(reply) }}
|
dangerouslySetInnerHTML={{ __html: renderMarkdown(reply) }}
|
||||||
/>
|
/>
|
||||||
<Citations sources={sources} />
|
<Citations sources={sources} />
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { Frown } from "react-feather";
|
import { Frown } from "react-feather";
|
||||||
import HistoricalMessage from "./HistoricalMessage";
|
import HistoricalMessage from "./HistoricalMessage";
|
||||||
import PromptReply from "./PromptReply";
|
import PromptReply from "./PromptReply";
|
||||||
// import paths from '../../../../../utils/paths';
|
|
||||||
|
|
||||||
export default function ChatHistory({ history = [], workspace }) {
|
export default function ChatHistory({ history = [], workspace }) {
|
||||||
if (history.length === 0) {
|
if (history.length === 0) {
|
||||||
@ -20,7 +19,7 @@ export default function ChatHistory({ history = [], workspace }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="h-[89%] pb-[100px] pt-[50px] md:pt-0 md:pb-5 mx-2 md:mx-0 overflow-y-scroll flex flex-col justify-between md:justify-start"
|
className="h-[89%] pb-[100px] md:pt-[50px] md:pt-0 md:pb-5 mx-2 md:mx-0 overflow-y-scroll flex flex-col justify-start no-scroll"
|
||||||
id="chat-history"
|
id="chat-history"
|
||||||
>
|
>
|
||||||
{history.map(
|
{history.map(
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import React, { useState, useRef } from "react";
|
import React, { useState, useRef } from "react";
|
||||||
|
import { isMobile } from "react-device-detect";
|
||||||
import { Loader, Menu, Send, X } from "react-feather";
|
import { Loader, Menu, Send, X } from "react-feather";
|
||||||
|
|
||||||
export default function PromptInput({
|
export default function PromptInput({
|
||||||
@ -24,6 +25,7 @@ export default function PromptInput({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const adjustTextArea = (event) => {
|
const adjustTextArea = (event) => {
|
||||||
|
if (isMobile) return false;
|
||||||
const element = event.target;
|
const element = event.target;
|
||||||
element.style.height = "1px";
|
element.style.height = "1px";
|
||||||
element.style.height =
|
element.style.height =
|
||||||
@ -37,10 +39,10 @@ export default function PromptInput({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full fixed md:absolute bottom-0 left-0">
|
<div className="w-full fixed md:absolute bottom-0 left-0 z-10">
|
||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className="flex flex-col gap-y-1 bg-transparentrounded-t-lg w-3/4 mx-auto"
|
className="flex flex-col gap-y-1 bg-white dark:bg-black-900 md:bg-transparent rounded-t-lg md:w-3/4 w-full mx-auto"
|
||||||
>
|
>
|
||||||
<div className="flex items-center py-2 px-4 rounded-lg">
|
<div className="flex items-center py-2 px-4 rounded-lg">
|
||||||
{/* Toggle selector? */}
|
{/* Toggle selector? */}
|
||||||
@ -64,7 +66,11 @@ export default function PromptInput({
|
|||||||
}}
|
}}
|
||||||
value={message}
|
value={message}
|
||||||
className="cursor-text max-h-[100px] md:min-h-[40px] block mx-2 md:mx-4 p-2.5 w-full text-[16px] md:text-sm rounded-lg border bg-gray-50 border-gray-300 placeholder-gray-400 text-gray-900 dark:text-white dark:bg-stone-600 dark:border-stone-700 dark:placeholder-stone-400"
|
className="cursor-text max-h-[100px] md:min-h-[40px] block mx-2 md:mx-4 p-2.5 w-full text-[16px] md:text-sm rounded-lg border bg-gray-50 border-gray-300 placeholder-gray-400 text-gray-900 dark:text-white dark:bg-stone-600 dark:border-stone-700 dark:placeholder-stone-400"
|
||||||
placeholder="Shift + Enter for newline. Enter to submit."
|
placeholder={
|
||||||
|
isMobile
|
||||||
|
? "Enter your message here."
|
||||||
|
: "Shift + Enter for newline. Enter to submit."
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
ref={formRef}
|
ref={formRef}
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import ChatHistory from "./ChatHistory";
|
|||||||
import PromptInput from "./PromptInput";
|
import PromptInput from "./PromptInput";
|
||||||
import Workspace from "../../../models/workspace";
|
import Workspace from "../../../models/workspace";
|
||||||
import handleChat from "../../../utils/chat";
|
import handleChat from "../../../utils/chat";
|
||||||
|
import { isMobile } from "react-device-detect";
|
||||||
|
import { SidebarMobileHeader } from "../../Sidebar";
|
||||||
|
|
||||||
export default function ChatContainer({ workspace, knownHistory = [] }) {
|
export default function ChatContainer({ workspace, knownHistory = [] }) {
|
||||||
const [message, setMessage] = useState("");
|
const [message, setMessage] = useState("");
|
||||||
@ -68,9 +70,10 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{ height: "calc(100% - 32px)" }}
|
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||||
className="transition-all duration-500 relative ml-[2px] mr-[8px] my-[16px] rounded-[26px] bg-white dark:bg-black-900 min-w-[82%] p-[18px] h-full overflow-y-scroll"
|
className="transition-all duration-500 relative md:ml-[2px] md:mr-[8px] md:my-[16px] md:rounded-[26px] bg-white dark:bg-black-900 w-full md:min-w-[82%] p-[18px] h-full overflow-y-scroll"
|
||||||
>
|
>
|
||||||
|
{isMobile && <SidebarMobileHeader />}
|
||||||
<div className="flex flex-col h-full w-full flex">
|
<div className="flex flex-col h-full w-full flex">
|
||||||
<ChatHistory history={chatHistory} workspace={workspace} />
|
<ChatHistory history={chatHistory} workspace={workspace} />
|
||||||
<PromptInput
|
<PromptInput
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
|
import { isMobile } from "react-device-detect";
|
||||||
import * as Skeleton from "react-loading-skeleton";
|
import * as Skeleton from "react-loading-skeleton";
|
||||||
import "react-loading-skeleton/dist/skeleton.css";
|
import "react-loading-skeleton/dist/skeleton.css";
|
||||||
|
|
||||||
export default function LoadingChat() {
|
export default function LoadingChat() {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{ height: "calc(100% - 32px)" }}
|
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||||
className="transition-all duration-500 relative ml-[2px] mr-[8px] my-[16px] rounded-[26px] bg-white dark:bg-black-900 min-w-[82%] p-[18px] h-full overflow-y-scroll"
|
className="transition-all duration-500 relative md:ml-[2px] md:mr-[8px] md:my-[16px] md:rounded-[26px] bg-white dark:bg-black-900 w-full md:min-w-[82%] p-[18px] h-full overflow-y-scroll"
|
||||||
>
|
>
|
||||||
<Skeleton.default
|
<Skeleton.default
|
||||||
height="100px"
|
height="100px"
|
||||||
@ -13,34 +14,34 @@ export default function LoadingChat() {
|
|||||||
baseColor={"#2a3a53"}
|
baseColor={"#2a3a53"}
|
||||||
highlightColor={"#395073"}
|
highlightColor={"#395073"}
|
||||||
count={1}
|
count={1}
|
||||||
className="max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
className="max-w-full md:max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
||||||
containerClassName="flex justify-start"
|
containerClassName="flex justify-start"
|
||||||
/>
|
/>
|
||||||
<Skeleton.default
|
<Skeleton.default
|
||||||
height="100px"
|
height="100px"
|
||||||
width="45%"
|
width={isMobile ? "70%" : "45%"}
|
||||||
baseColor={"#2a3a53"}
|
baseColor={"#2a3a53"}
|
||||||
highlightColor={"#395073"}
|
highlightColor={"#395073"}
|
||||||
count={1}
|
count={1}
|
||||||
className="max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
className="max-w-full md:max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
||||||
containerClassName="flex justify-end"
|
containerClassName="flex justify-end"
|
||||||
/>
|
/>
|
||||||
<Skeleton.default
|
<Skeleton.default
|
||||||
height="100px"
|
height="100px"
|
||||||
width="30%"
|
width={isMobile ? "55%" : "30%"}
|
||||||
baseColor={"#2a3a53"}
|
baseColor={"#2a3a53"}
|
||||||
highlightColor={"#395073"}
|
highlightColor={"#395073"}
|
||||||
count={1}
|
count={1}
|
||||||
className="max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
className="max-w-full md:max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
||||||
containerClassName="flex justify-start"
|
containerClassName="flex justify-start"
|
||||||
/>
|
/>
|
||||||
<Skeleton.default
|
<Skeleton.default
|
||||||
height="100px"
|
height="100px"
|
||||||
width="25%"
|
width={isMobile ? "88%" : "25%"}
|
||||||
baseColor={"#2a3a53"}
|
baseColor={"#2a3a53"}
|
||||||
highlightColor={"#395073"}
|
highlightColor={"#395073"}
|
||||||
count={1}
|
count={1}
|
||||||
className="max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
className="max-w-full md:max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
||||||
containerClassName="flex justify-end"
|
containerClassName="flex justify-end"
|
||||||
/>
|
/>
|
||||||
<Skeleton.default
|
<Skeleton.default
|
||||||
@ -49,7 +50,7 @@ export default function LoadingChat() {
|
|||||||
baseColor={"#2a3a53"}
|
baseColor={"#2a3a53"}
|
||||||
highlightColor={"#395073"}
|
highlightColor={"#395073"}
|
||||||
count={1}
|
count={1}
|
||||||
className="max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
className="max-w-full md:max-w-[75%] p-4 rounded-b-2xl rounded-tr-2xl rounded-tl-sm mt-6"
|
||||||
containerClassName="flex justify-start"
|
containerClassName="flex justify-start"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export default function WorkspaceChat({ loading, workspace }) {
|
|||||||
}, [workspace, loading]);
|
}, [workspace, loading]);
|
||||||
|
|
||||||
if (loadingHistory) return <LoadingChat />;
|
if (loadingHistory) return <LoadingChat />;
|
||||||
if (!loading && !loadingHistory && !workspace)
|
if (!loading && !loadingHistory && !workspace) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{loading === false && !workspace && (
|
{loading === false && !workspace && (
|
||||||
@ -57,6 +57,7 @@ export default function WorkspaceChat({ loading, workspace }) {
|
|||||||
<LoadingChat />
|
<LoadingChat />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return <ChatContainer workspace={workspace} knownHistory={history} />;
|
return <ChatContainer workspace={workspace} knownHistory={history} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import ChatPlaceholder from "../../components/WorkspaceChat/LoadingChat";
|
|||||||
import PasswordModal, {
|
import PasswordModal, {
|
||||||
usePasswordModal,
|
usePasswordModal,
|
||||||
} from "../../components/Modals/Password";
|
} from "../../components/Modals/Password";
|
||||||
|
import { isMobile } from "react-device-detect";
|
||||||
|
|
||||||
export default function Main() {
|
export default function Main() {
|
||||||
const { requiresAuth } = usePasswordModal();
|
const { requiresAuth } = usePasswordModal();
|
||||||
@ -14,7 +15,7 @@ export default function Main() {
|
|||||||
<>
|
<>
|
||||||
{requiresAuth && <PasswordModal />}
|
{requiresAuth && <PasswordModal />}
|
||||||
<div className="w-screen h-screen overflow-hidden bg-orange-100 dark:bg-stone-700 flex">
|
<div className="w-screen h-screen overflow-hidden bg-orange-100 dark:bg-stone-700 flex">
|
||||||
<SidebarPlaceholder />
|
{!isMobile && <SidebarPlaceholder />}
|
||||||
<ChatPlaceholder />
|
<ChatPlaceholder />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@ -23,7 +24,7 @@ export default function Main() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-screen h-screen overflow-hidden bg-orange-100 dark:bg-stone-700 flex">
|
<div className="w-screen h-screen overflow-hidden bg-orange-100 dark:bg-stone-700 flex">
|
||||||
<Sidebar />
|
{!isMobile && <Sidebar />}
|
||||||
<DefaultChatContainer />
|
<DefaultChatContainer />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import ChatPlaceholder from "../../components/WorkspaceChat/LoadingChat";
|
|||||||
import PasswordModal, {
|
import PasswordModal, {
|
||||||
usePasswordModal,
|
usePasswordModal,
|
||||||
} from "../../components/Modals/Password";
|
} from "../../components/Modals/Password";
|
||||||
|
import { isMobile } from "react-device-detect";
|
||||||
|
|
||||||
export default function WorkspaceChat() {
|
export default function WorkspaceChat() {
|
||||||
const { requiresAuth } = usePasswordModal();
|
const { requiresAuth } = usePasswordModal();
|
||||||
@ -16,7 +17,7 @@ export default function WorkspaceChat() {
|
|||||||
<>
|
<>
|
||||||
{requiresAuth && <PasswordModal />}
|
{requiresAuth && <PasswordModal />}
|
||||||
<div className="w-screen h-screen overflow-hidden bg-orange-100 dark:bg-stone-700 flex">
|
<div className="w-screen h-screen overflow-hidden bg-orange-100 dark:bg-stone-700 flex">
|
||||||
<SidebarPlaceholder />
|
{!isMobile && <SidebarPlaceholder />}
|
||||||
<ChatPlaceholder />
|
<ChatPlaceholder />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@ -43,7 +44,7 @@ function ShowWorkspaceChat() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-screen h-screen overflow-hidden bg-orange-100 dark:bg-stone-700 flex">
|
<div className="w-screen h-screen overflow-hidden bg-orange-100 dark:bg-stone-700 flex">
|
||||||
<Sidebar />
|
{!isMobile && <Sidebar />}
|
||||||
<WorkspaceChatContainer loading={loading} workspace={workspace} />
|
<WorkspaceChatContainer loading={loading} workspace={workspace} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user