θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export default function EmbedderItem({
return (
<div
onClick={() => onClick(value)}
className={`w-full hover:bg-white/10 p-2 rounded-md hover:cursor-pointer ${
checked && "bg-white/10"
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-white/10 ${
checked ? "bg-white/10" : ""
}`}
>
<input
Expand All @@ -28,8 +28,8 @@ export default function EmbedderItem({
className="w-10 h-10 rounded-md"
/>
<div className="flex flex-col">
<div className="text-sm font-semibold">{name}</div>
<div className="mt-1 text-xs text-white/60">{description}</div>
<div className="text-sm font-semibold text-white">{name}</div>
<div className="mt-1 text-xs text-[#D2D5DB]">{description}</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default function NativeEmbeddingOptions() {
return (
<div className="w-full h-20 items-center justify-center flex">
<div className="w-full h-10 items-center flex">
<p className="text-sm font-base text-white text-opacity-60">
There is no set up required when using AnythingLLM's native embedding
engine.
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/LLMSelection/LLMItem/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export default function LLMItem({
return (
<div
onClick={() => onClick(value)}
className={`w-full hover:bg-white/10 p-2 rounded-md hover:cursor-pointer ${
checked && "bg-white/10"
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-white/10 ${
checked ? "bg-white/10" : ""
}`}
>
<input
Expand All @@ -28,8 +28,8 @@ export default function LLMItem({
className="w-10 h-10 rounded-md"
/>
<div className="flex flex-col">
<div className="text-sm font-semibold">{name}</div>
<div className="mt-1 text-xs text-white/60">{description}</div>
<div className="text-sm font-semibold text-white">{name}</div>
<div className="mt-1 text-xs text-[#D2D5DB]">{description}</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default function LanceDBOptions() {
return (
<div className="w-full h-10 items-center justify-center flex">
<div className="w-full h-10 items-center flex">
<p className="text-sm font-base text-white text-opacity-60">
There is no configuration needed for LanceDB.
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function VectorDBItem({
return (
<div
onClick={() => onClick(value)}
className={`w-full hover:bg-white/10 p-2 rounded-md hover:cursor-pointer ${
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-white/10 ${
checked ? "bg-white/10" : ""
}`}
>
Expand All @@ -28,8 +28,8 @@ export default function VectorDBItem({
className="w-10 h-10 rounded-md"
/>
<div className="flex flex-col">
<div className="text-sm font-semibold">{name}</div>
<div className="mt-1 text-xs text-white/60">{description}</div>
<div className="text-sm font-semibold text-white">{name}</div>
<div className="mt-1 text-xs text-[#D2D5DB]">{description}</div>
</div>
</div>
</div>
Expand Down
29 changes: 29 additions & 0 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -633,3 +633,32 @@ does not extend the close button beyond the viewport. */
.upload-modal-arrow {
margin-top: 25%;
}

/* Scrollbar container */
.white-scrollbar {
overflow-y: scroll;
scrollbar-width: thin;
scrollbar-color: #ffffff #18181b;
margin-right: 8px;
}

/* Webkit browsers (Chrome, Safari) */
.white-scrollbar::-webkit-scrollbar {
width: 3px;
background-color: #18181b;
}

.white-scrollbar::-webkit-scrollbar-track {
background-color: #18181b;
margin-right: 8px;
}

.white-scrollbar::-webkit-scrollbar-thumb {
background-color: #ffffff;
border-radius: 4px;
border: 2px solid #18181b;
}

.white-scrollbar::-webkit-scrollbar-thumb:hover {
background-color: #cccccc;
}
154 changes: 106 additions & 48 deletions frontend/src/pages/GeneralSettings/EmbeddingPreference/index.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useEffect, useState, useRef } from "react";
import Sidebar from "@/components/SettingsSidebar";
import { isMobile } from "react-device-detect";
import System from "@/models/system";
Expand All @@ -16,7 +16,7 @@ import LocalAiOptions from "@/components/EmbeddingSelection/LocalAiOptions";
import NativeEmbeddingOptions from "@/components/EmbeddingSelection/NativeEmbeddingOptions";
import OllamaEmbeddingOptions from "@/components/EmbeddingSelection/OllamaOptions";
import EmbedderItem from "@/components/EmbeddingSelection/EmbedderItem";
import { MagnifyingGlass } from "@phosphor-icons/react";
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
import { useModal } from "@/hooks/useModal";
import ModalWrapper from "@/components/ModalWrapper";

Expand All @@ -29,6 +29,8 @@ export default function GeneralEmbeddingPreference() {
const [searchQuery, setSearchQuery] = useState("");
const [filteredEmbedders, setFilteredEmbedders] = useState([]);
const [selectedEmbedder, setSelectedEmbedder] = useState(null);
const [searchMenuOpen, setSearchMenuOpen] = useState(false);
const searchInputRef = useRef(null);
const { isOpen, openModal, closeModal } = useModal();

const handleSubmit = async (e) => {
Expand Down Expand Up @@ -65,10 +67,21 @@ export default function GeneralEmbeddingPreference() {
};

const updateChoice = (selection) => {
setSearchQuery("");
setSelectedEmbedder(selection);
setSearchMenuOpen(false);
setHasChanges(true);
};

const handleXButton = () => {
if (searchQuery.length > 0) {
setSearchQuery("");
if (searchInputRef.current) searchInputRef.current.value = "";
} else {
setSearchMenuOpen(!searchMenuOpen);
}
};

useEffect(() => {
async function fetchKeys() {
const _settings = await System.keys();
Expand Down Expand Up @@ -126,6 +139,10 @@ export default function GeneralEmbeddingPreference() {
setFilteredEmbedders(filtered);
}, [searchQuery, selectedEmbedder]);

const selectedEmbedderObject = EMBEDDERS.find(
(embedder) => embedder.value === selectedEmbedder
);

return (
<div className="w-screen h-screen overflow-hidden bg-sidebar flex">
<Sidebar />
Expand Down Expand Up @@ -174,55 +191,96 @@ export default function GeneralEmbeddingPreference() {
format which AnythingLLM can use to process.
</p>
</div>
<div className="text-sm font-medium text-white mt-6 mb-4">
Embedding Providers
<div className="text-base font-bold text-white mt-6 mb-4">
Embedding Provider
</div>
<div className="w-full">
<div className="w-full relative border-slate-300/20 shadow border-4 rounded-xl text-white">
<div className="w-full p-4 absolute top-0 rounded-t-lg backdrop-blur-sm">
<div className="w-full flex items-center sticky top-0">
<MagnifyingGlass
size={16}
weight="bold"
className="absolute left-4 z-30 text-white"
/>
<input
type="text"
placeholder="Search Embedding providers"
className="bg-zinc-600 z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:border-white text-white"
onChange={(e) => setSearchQuery(e.target.value)}
autoComplete="off"
onKeyDown={(e) => {
if (e.key === "Enter") e.preventDefault();
}}
/>
</div>
</div>
<div className="px-4 pt-[70px] flex flex-col gap-y-1 max-h-[390px] overflow-y-auto no-scroll pb-4">
{filteredEmbedders.map((embedder) => {
return (
<EmbedderItem
key={embedder.name}
name={embedder.name}
value={embedder.value}
image={embedder.logo}
description={embedder.description}
checked={selectedEmbedder === embedder.value}
onClick={() => updateChoice(embedder.value)}
<div className="relative">
{searchMenuOpen && (
<div
className="fixed top-0 left-0 w-full h-full bg-black bg-opacity-70 backdrop-blur-sm z-10"
onClick={() => setSearchMenuOpen(false)}
/>
)}
{searchMenuOpen ? (
<div className="absolute top-0 left-0 w-full max-w-[640px] max-h-[310px] overflow-auto white-scrollbar min-h-[64px] bg-[#18181B] rounded-lg flex flex-col justify-between cursor-pointer border-2 border-[#46C8FF] z-20">
<div className="w-full flex flex-col gap-y-1">
<div className="flex items-center sticky top-0 border-b border-[#9CA3AF] mx-4 bg-[#18181B]">
<MagnifyingGlass
size={20}
weight="bold"
className="absolute left-4 z-30 text-white -ml-4 my-2"
/>
<input
type="text"
name="embedder-search"
autoComplete="off"
placeholder="Search all embedding providers"
className="-ml-4 my-2 bg-transparent z-20 pl-12 h-[38px] w-full px-4 py-1 text-sm outline-none focus:border-white text-white placeholder:text-white placeholder:font-medium"
onChange={(e) => setSearchQuery(e.target.value)}
ref={searchInputRef}
onKeyDown={(e) => {
if (e.key === "Enter") e.preventDefault();
}}
/>
<X
size={20}
weight="bold"
className="cursor-pointer text-white hover:text-[#9CA3AF]"
onClick={handleXButton}
/>
);
})}
</div>
<div className="flex-1 pl-4 pr-2 flex flex-col gap-y-1 overflow-y-auto white-scrollbar pb-4">
{filteredEmbedders.map((embedder) => (
<EmbedderItem
key={embedder.name}
name={embedder.name}
value={embedder.value}
image={embedder.logo}
description={embedder.description}
checked={selectedEmbedder === embedder.value}
onClick={() => updateChoice(embedder.value)}
/>
))}
</div>
</div>
</div>
</div>
<div
onChange={() => setHasChanges(true)}
className="mt-4 flex flex-col gap-y-1"
>
{selectedEmbedder &&
EMBEDDERS.find(
(embedder) => embedder.value === selectedEmbedder
)?.options}
</div>
) : (
<button
className="w-full max-w-[640px] h-[64px] bg-[#18181B] rounded-lg flex items-center p-[14px] justify-between cursor-pointer border-2 border-transparent hover:border-[#46C8FF] transition-all duration-300"
type="button"
onClick={() => setSearchMenuOpen(true)}
>
<div className="flex gap-x-4 items-center">
<img
src={selectedEmbedderObject.logo}
alt={`${selectedEmbedderObject.name} logo`}
className="w-10 h-10 rounded-md"
/>
<div className="flex flex-col text-left">
<div className="text-sm font-semibold text-white">
{selectedEmbedderObject.name}
</div>
<div className="mt-1 text-xs text-[#D2D5DB]">
{selectedEmbedderObject.description}
</div>
</div>
</div>
<CaretUpDown
size={24}
weight="bold"
className="text-white"
/>
</button>
)}
</div>
<div
onChange={() => setHasChanges(true)}
className="mt-4 flex flex-col gap-y-1"
>
{selectedEmbedder &&
EMBEDDERS.find(
(embedder) => embedder.value === selectedEmbedder
)?.options}
</div>
</div>
</form>
Expand Down
Loading