mirror of
https://github.com/Mintplex-Labs/vector-admin.git
synced 2026-07-19 13:16:03 -04:00
implement header update connector and sync buttons/image glitch fixes
This commit is contained in:
@@ -15,10 +15,12 @@ import ConnectorCard from './Connector';
|
||||
import truncate from 'truncate';
|
||||
|
||||
import ChromaLogo from '../../images/vectordbs/chroma.png';
|
||||
import PineconeLogo from '../../images/vectordbs/pinecone-inverted.png';
|
||||
import PineconeLogoInverted from '../../images/vectordbs/pinecone-inverted.png';
|
||||
import PineconeLogo from '../../images/vectordbs/pinecone.png';
|
||||
import qDrantLogo from '../../images/vectordbs/qdrant.png';
|
||||
import WeaviateLogo from '../../images/vectordbs/weaviate.png';
|
||||
import { GearSix } from '@phosphor-icons/react';
|
||||
import { titleCase } from 'title-case';
|
||||
|
||||
export default function Dashboard() {
|
||||
const { slug } = useParams();
|
||||
@@ -115,12 +117,21 @@ export default function Dashboard() {
|
||||
>
|
||||
{!!organization && (
|
||||
<div className="mb-4 grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6 xl:grid-cols-4 2xl:gap-7.5">
|
||||
<UpdateConnectorModal
|
||||
organization={organization}
|
||||
connector={connector}
|
||||
onUpdate={(newConnector: any) => setConnector(newConnector)}
|
||||
/>
|
||||
<SyncConnectorModal
|
||||
organization={organization}
|
||||
connector={connector}
|
||||
/>
|
||||
{/* <ConnectorCard
|
||||
knownConnector={connector}
|
||||
organization={organization}
|
||||
workspaces={workspaces}
|
||||
/>
|
||||
<ApiKeyCard organization={organization} /> */}
|
||||
/> */}
|
||||
{/* <ApiKeyCard organization={organization} /> */}
|
||||
</div>
|
||||
)}
|
||||
<Statistics organization={organization} />
|
||||
@@ -161,7 +172,7 @@ function OrganizationHeader({
|
||||
logo = WeaviateLogo;
|
||||
break;
|
||||
default:
|
||||
logo = PineconeLogo;
|
||||
logo = PineconeLogoInverted;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -198,9 +209,7 @@ function OrganizationHeader({
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
onClick={() =>
|
||||
window.document?.getElementById('edit-connector-modal')?.showModal()
|
||||
}
|
||||
onClick={() => alert('Settings clicked.')}
|
||||
className="flex h-11 w-11 items-center justify-center rounded-lg border-2 border-white border-opacity-20 text-white transition-all duration-300 hover:bg-opacity-5"
|
||||
>
|
||||
<GearSix size={28} />
|
||||
@@ -209,3 +218,522 @@ function OrganizationHeader({
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const UpdateConnectorModal = ({
|
||||
organization,
|
||||
connector,
|
||||
onUpdate,
|
||||
}: {
|
||||
organization: any;
|
||||
connector: any;
|
||||
onUpdate: (newConnector: any) => void;
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [type, setType] = useState(connector.type);
|
||||
const [error, setError] = useState<null | string>(null);
|
||||
const [success, setSuccess] = useState<null | boolean>(false);
|
||||
const settings = JSON.parse(connector.settings);
|
||||
|
||||
const handleSubmit = async (e: any) => {
|
||||
e.preventDefault();
|
||||
setError(null);
|
||||
setLoading(true);
|
||||
const data = { type };
|
||||
const form = new FormData(e.target);
|
||||
for (var [_k, value] of form.entries()) {
|
||||
if (_k.includes('::')) {
|
||||
const [_key, __key] = _k.split('::');
|
||||
if (!data.hasOwnProperty(_key)) data[_key] = {};
|
||||
data[_key][__key] = value;
|
||||
} else {
|
||||
data[_k] = value;
|
||||
}
|
||||
}
|
||||
|
||||
const { connector, error } = await Organization.updateConnector(
|
||||
organization.slug,
|
||||
data
|
||||
);
|
||||
if (!connector) {
|
||||
setLoading(false);
|
||||
setError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
setSuccess(true);
|
||||
setTimeout(() => {
|
||||
onUpdate(connector);
|
||||
setSuccess(false);
|
||||
}, 1500);
|
||||
};
|
||||
|
||||
return (
|
||||
<dialog
|
||||
id="edit-connector-modal"
|
||||
className="w-1/2 rounded-lg"
|
||||
onClick={(event) =>
|
||||
event.target == event.currentTarget && event.currentTarget?.close()
|
||||
}
|
||||
>
|
||||
<div className="rounded-sm bg-white p-[20px]">
|
||||
<div className="px-6.5 py-4">
|
||||
<h3 className="font-medium text-black dark:text-white">
|
||||
Update Vector Database Connection
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500">
|
||||
Currently connected to a {connector.type} vector database instance.
|
||||
You can update your configuration settings here if they have
|
||||
changed.
|
||||
</p>
|
||||
</div>
|
||||
{loading ? (
|
||||
<div className="px-6.5">
|
||||
<div className="mb-4.5 flex w-full justify-center">
|
||||
<PreLoader />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<ul className="mx-6 flex w-full flex-wrap gap-6">
|
||||
<li onClick={() => setType('chroma')} className="w-[250px]">
|
||||
<input
|
||||
name="type"
|
||||
type="checkbox"
|
||||
value="chroma"
|
||||
className="peer hidden"
|
||||
checked={type === 'chroma'}
|
||||
formNoValidate={true}
|
||||
/>
|
||||
<label className="inline-flex h-full w-full cursor-pointer items-center justify-between rounded-lg border-2 border-gray-200 bg-white p-5 text-gray-500 hover:bg-gray-50 hover:text-gray-600 peer-checked:border-blue-600 peer-checked:bg-blue-50 peer-checked:text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 dark:peer-checked:text-gray-300">
|
||||
<div className="block">
|
||||
<img
|
||||
src={ChromaLogo}
|
||||
className="mb-2 h-10 w-10 rounded-full"
|
||||
/>
|
||||
<div className="w-full text-lg font-semibold">Chroma</div>
|
||||
<div className="flex w-full flex-col gap-y-1 text-sm">
|
||||
<p className="text-xs text-slate-400">trychroma.com</p>
|
||||
Open source vector database you can host yourself.
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
<li onClick={() => setType('pinecone')} className="w-[250px]">
|
||||
<input
|
||||
name="type"
|
||||
type="checkbox"
|
||||
value="pinecone"
|
||||
className="peer hidden"
|
||||
checked={type === 'pinecone'}
|
||||
formNoValidate={true}
|
||||
/>
|
||||
<label className="inline-flex h-full w-full cursor-pointer items-center justify-between rounded-lg border-2 border-gray-200 bg-white p-5 text-gray-500 hover:bg-gray-50 hover:text-gray-600 peer-checked:border-blue-600 peer-checked:bg-blue-50 peer-checked:text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 dark:peer-checked:text-gray-300">
|
||||
<div className="block">
|
||||
<img
|
||||
src={PineconeLogo}
|
||||
className="mb-2 h-10 w-10 rounded-full"
|
||||
/>
|
||||
<div className="w-full text-lg font-semibold">Pinecone</div>
|
||||
<div className="flex w-full flex-col gap-y-1 text-sm">
|
||||
<p className="text-xs text-slate-400">pinecone.io</p>
|
||||
Cloud-hosted vector database.
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
<li onClick={() => setType('qdrant')} className="w-[250px]">
|
||||
<input
|
||||
name="type"
|
||||
type="checkbox"
|
||||
value="qdrant"
|
||||
className="peer hidden"
|
||||
checked={type === 'qdrant'}
|
||||
formNoValidate={true}
|
||||
/>
|
||||
<label className="inline-flex h-full w-full cursor-pointer items-center justify-between rounded-lg border-2 border-gray-200 bg-white p-5 text-gray-500 hover:bg-gray-50 hover:text-gray-600 peer-checked:border-blue-600 peer-checked:bg-blue-50 peer-checked:text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 dark:peer-checked:text-gray-300">
|
||||
<div className="block">
|
||||
<img
|
||||
src={qDrantLogo}
|
||||
className="mb-2 h-10 w-10 rounded-full"
|
||||
/>
|
||||
<div className="w-full text-lg font-semibold">qDrant</div>
|
||||
<div className="flex w-full flex-col gap-y-1 text-sm">
|
||||
<p className="text-xs text-slate-400">qdrant.tech</p>
|
||||
Open-source & hosted vector database.
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
<li onClick={() => setType('weaviate')} className="w-[250px]">
|
||||
<input
|
||||
name="type"
|
||||
type="checkbox"
|
||||
value="weaviate"
|
||||
className="peer hidden"
|
||||
checked={type === 'weaviate'}
|
||||
formNoValidate={true}
|
||||
/>
|
||||
<label className="inline-flex h-full w-full cursor-pointer items-center justify-between rounded-lg border-2 border-gray-200 bg-white p-5 text-gray-500 hover:bg-gray-50 hover:text-gray-600 peer-checked:border-blue-600 peer-checked:bg-blue-50 peer-checked:text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 dark:peer-checked:text-gray-300">
|
||||
<div className="block">
|
||||
<img
|
||||
src={WeaviateLogo}
|
||||
className="mb-2 h-10 w-10 rounded-full"
|
||||
/>
|
||||
<div className="w-full text-lg font-semibold">Weaviate</div>
|
||||
<div className="flex w-full flex-col gap-y-1 text-sm">
|
||||
<p className="text-xs text-slate-400">weaviate.io</p>
|
||||
Open-source & hosted vector database.
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{type === 'chroma' && (
|
||||
<div className="mx-6 my-4 flex flex-col gap-y-6">
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::instanceURL"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Instance URL
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
This is the URL your chroma instance is reachable at.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
name="settings::instanceURL"
|
||||
autoComplete="off"
|
||||
type="url"
|
||||
defaultValue={settings.instanceURL}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="https://my-domain.com:8000"
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::authToken"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
API Header & Key
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
If your hosted Chroma instance is protected by an API key
|
||||
- enter the header and api key here.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex w-full items-center gap-x-4">
|
||||
<input
|
||||
name="settings::authTokenHeader"
|
||||
autoComplete="off"
|
||||
type="text"
|
||||
defaultValue={settings.authTokenHeader}
|
||||
className="block w-[20%] rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="X-Api-Key"
|
||||
/>
|
||||
<input
|
||||
name="settings::authToken"
|
||||
autoComplete="off"
|
||||
type="password"
|
||||
defaultValue={settings.authToken}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="sk-myApiKeyToAccessMyChromaInstance"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{type === 'pinecone' && (
|
||||
<div className="mx-6 my-4 flex flex-col gap-y-6">
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::environment"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Pinecone Environment
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
You can find this on your Pinecone index.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
name="settings::environment"
|
||||
autoComplete="off"
|
||||
type="text"
|
||||
defaultValue={settings.environment}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="us-west4-gcp-free"
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::index"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Pinecone Index
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
You can find this on your Pinecone index.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
name="settings::index"
|
||||
autoComplete="off"
|
||||
type="text"
|
||||
defaultValue={settings.index}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="my-index"
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::apiKey"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
API Key
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
If your hosted Chroma instance is protected by an API key
|
||||
- enter it here.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
name="settings::apiKey"
|
||||
autoComplete="off"
|
||||
type="password"
|
||||
defaultValue={settings.apiKey}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="ee1051-xxxx-xxxx-xxxx"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{type === 'qdrant' && (
|
||||
<div className="mx-6 my-4 flex flex-col gap-y-6">
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::clusterUrl"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
qDrant Cluster URL
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
You can find this in your cloud hosted qDrant cluster or
|
||||
just using the URL to your local docker container.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
name="settings::clusterUrl"
|
||||
autoComplete="off"
|
||||
type="url"
|
||||
defaultValue={settings.clusterUrl}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="https://6b3a2d01-3b3f-4339-84e9-ead94f28a844.us-east-1-0.aws.cloud.qdrant.io"
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::apiKey"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
API Key
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
(optional) If you are using qDrant cloud you will need an
|
||||
API key.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
name="settings::apiKey"
|
||||
autoComplete="off"
|
||||
type="password"
|
||||
defaultValue={settings.apiKey}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="ee1051-xxxx-xxxx-xxxx"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{type === 'weaviate' && (
|
||||
<div className="mx-6 my-4 flex flex-col gap-y-6">
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::clusterUrl"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Weaviate Cluster URL
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
You can find this in your cloud hosted Weaviate cluster or
|
||||
just using the URL to your local docker container.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
name="settings::clusterUrl"
|
||||
autoComplete="off"
|
||||
type="url"
|
||||
defaultValue={settings.clusterUrl}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="https://my-sandbox-b5vipdmw.weaviate.network"
|
||||
required={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className="mb-2 flex flex-col gap-y-1">
|
||||
<label
|
||||
htmlFor="settings::apiKey"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
API Key
|
||||
</label>
|
||||
<p className="text-xs text-gray-500">
|
||||
(optional) If you are using Weaviate cloud you will need
|
||||
an API key.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
name="settings::apiKey"
|
||||
autoComplete="off"
|
||||
type="password"
|
||||
defaultValue={settings.apiKey}
|
||||
className="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
placeholder="ee1051-xxxx-xxxx-xxxx"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="w-full px-6">
|
||||
{error && (
|
||||
<p className="my-2 w-full rounded-lg border-red-800 bg-red-50 px-4 py-2 text-red-800">
|
||||
{error}
|
||||
</p>
|
||||
)}
|
||||
{success && (
|
||||
<p className="my-2 w-full rounded-lg border-green-800 bg-green-50 px-4 py-2 text-green-800">
|
||||
Connector changes saved
|
||||
</p>
|
||||
)}
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full rounded-lg border border-blue-600 py-2 text-center text-blue-600 hover:bg-blue-600 hover:text-white"
|
||||
>
|
||||
Connect to Vector Database
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</dialog>
|
||||
);
|
||||
};
|
||||
|
||||
const SyncConnectorModal = ({
|
||||
organization,
|
||||
connector,
|
||||
}: {
|
||||
organization: any;
|
||||
connector: any;
|
||||
}) => {
|
||||
const [synced, setSynced] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<null | string>(null);
|
||||
const sync = async () => {
|
||||
setError(null);
|
||||
setLoading(true);
|
||||
const { job, error } = await Organization.syncConnector(
|
||||
organization.slug,
|
||||
connector.id
|
||||
);
|
||||
|
||||
if (!job) {
|
||||
setError(error);
|
||||
setLoading(false);
|
||||
setSynced(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
setSynced(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<dialog
|
||||
id="sync-connector-modal"
|
||||
className="w-1/3 rounded-lg"
|
||||
onClick={(event) =>
|
||||
event.target == event.currentTarget && event.currentTarget?.close()
|
||||
}
|
||||
>
|
||||
<div className="overflow-y-scroll rounded-sm bg-white p-[20px]">
|
||||
<div className="px-6.5 py-4">
|
||||
<h3 className="font-medium text-black dark:text-white">
|
||||
Sync Vector Database Connection
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500">
|
||||
Automatically sync existing information in your{' '}
|
||||
{titleCase(connector.type)}{' '}
|
||||
{connector.type === 'chroma' ? 'collections' : 'namespaces'} so you
|
||||
can manage it more easily. This process can take a long time to
|
||||
complete depending on how much data you have embedded already.
|
||||
<br />
|
||||
<br />
|
||||
Once you start this process you can check on its progress in the{' '}
|
||||
<a
|
||||
href={paths.jobs(organization)}
|
||||
className="font-semibold text-blue-500"
|
||||
>
|
||||
job queue.
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full px-6">
|
||||
{error && (
|
||||
<p className="my-2 w-full rounded-lg border-red-800 bg-red-50 px-4 py-2 text-red-800">
|
||||
{error}
|
||||
</p>
|
||||
)}
|
||||
{synced ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => window.location.replace(paths.jobs(organization))}
|
||||
className="w-full rounded-lg py-2 text-center text-gray-600 hover:bg-gray-400 hover:text-white"
|
||||
>
|
||||
Check progress
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
disabled={loading}
|
||||
onClick={sync}
|
||||
className="w-full rounded-lg bg-blue-600 py-2 text-center text-white"
|
||||
>
|
||||
{loading ? 'Synchronizing...' : 'Synchronize embeddings'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,7 +17,8 @@ import { CaretDown } from '@phosphor-icons/react';
|
||||
import truncate from 'truncate';
|
||||
|
||||
import ChromaLogo from '../../images/vectordbs/chroma.png';
|
||||
import PineconeLogo from '../../images/vectordbs/pinecone-inverted.png';
|
||||
import PineconeLogoInverted from '../../images/vectordbs/pinecone-inverted.png';
|
||||
import PineconeLogo from '../../images/vectordbs/pinecone.png';
|
||||
import qDrantLogo from '../../images/vectordbs/qdrant.png';
|
||||
import WeaviateLogo from '../../images/vectordbs/weaviate.png';
|
||||
|
||||
@@ -795,7 +796,7 @@ function WorkspaceViewHeader({
|
||||
logo = WeaviateLogo;
|
||||
break;
|
||||
default:
|
||||
logo = PineconeLogo;
|
||||
logo = PineconeLogoInverted;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user