mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-30 00:53:14 +00:00
complete_stream: no storing for api key req, fe:update shared conv
This commit is contained in:
@@ -1,8 +1,22 @@
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSelector } from 'react-redux';
|
||||
import {
|
||||
selectSourceDocs,
|
||||
selectSelectedDocs,
|
||||
selectChunks,
|
||||
selectPrompt,
|
||||
} from '../preferences/preferenceSlice';
|
||||
import Dropdown from '../components/Dropdown';
|
||||
import { Doc } from '../models/misc';
|
||||
import Spinner from '../assets/spinner.svg';
|
||||
import Exit from '../assets/exit.svg';
|
||||
const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com';
|
||||
const embeddingsName =
|
||||
import.meta.env.VITE_EMBEDDINGS_NAME ||
|
||||
'huggingface_sentence-transformers/all-mpnet-base-v2';
|
||||
|
||||
type StatusType = 'loading' | 'idle' | 'fetched' | 'failed';
|
||||
|
||||
export const ShareConversationModal = ({
|
||||
close,
|
||||
@@ -11,26 +25,87 @@ export const ShareConversationModal = ({
|
||||
close: () => void;
|
||||
conversationId: string;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const domain = window.location.origin;
|
||||
|
||||
const [identifier, setIdentifier] = useState<null | string>(null);
|
||||
const [isCopied, setIsCopied] = useState(false);
|
||||
type StatusType = 'loading' | 'idle' | 'fetched' | 'failed';
|
||||
const [status, setStatus] = useState<StatusType>('idle');
|
||||
const { t } = useTranslation();
|
||||
const domain = window.location.origin;
|
||||
const [allowPrompt, setAllowPrompt] = useState<boolean>(false);
|
||||
|
||||
const sourceDocs = useSelector(selectSourceDocs);
|
||||
const preSelectedDoc = useSelector(selectSelectedDocs);
|
||||
const selectedPrompt = useSelector(selectPrompt);
|
||||
const selectedChunk = useSelector(selectChunks);
|
||||
|
||||
const extractDocPaths = (docs: Doc[]) =>
|
||||
docs
|
||||
? docs
|
||||
.filter((doc) => doc.model === embeddingsName)
|
||||
.map((doc: Doc) => {
|
||||
let namePath = doc.name;
|
||||
if (doc.language === namePath) {
|
||||
namePath = '.project';
|
||||
}
|
||||
let docPath = 'default';
|
||||
if (doc.location === 'local') {
|
||||
docPath = 'local' + '/' + doc.name + '/';
|
||||
} else if (doc.location === 'remote') {
|
||||
docPath =
|
||||
doc.language +
|
||||
'/' +
|
||||
namePath +
|
||||
'/' +
|
||||
doc.version +
|
||||
'/' +
|
||||
doc.model +
|
||||
'/';
|
||||
}
|
||||
return {
|
||||
label: doc.name,
|
||||
value: docPath,
|
||||
};
|
||||
})
|
||||
: [];
|
||||
|
||||
const [sourcePath, setSourcePath] = useState<{
|
||||
label: string;
|
||||
value: string;
|
||||
} | null>(preSelectedDoc ? extractDocPaths([preSelectedDoc])[0] : null);
|
||||
|
||||
const handleCopyKey = (url: string) => {
|
||||
navigator.clipboard.writeText(url);
|
||||
setIsCopied(true);
|
||||
};
|
||||
|
||||
const togglePromptPermission = () => {
|
||||
setAllowPrompt(!allowPrompt);
|
||||
setStatus('idle');
|
||||
setIdentifier(null);
|
||||
};
|
||||
|
||||
const shareCoversationPublicly: (isPromptable: boolean) => void = (
|
||||
isPromptable = false,
|
||||
) => {
|
||||
setStatus('loading');
|
||||
const payload: {
|
||||
conversation_id: string;
|
||||
chunks?: string;
|
||||
prompt_id?: string;
|
||||
source?: string;
|
||||
} = { conversation_id: conversationId };
|
||||
if (isPromptable) {
|
||||
payload.chunks = selectedChunk;
|
||||
payload.prompt_id = selectedPrompt.id;
|
||||
sourcePath && (payload.source = sourcePath.value);
|
||||
}
|
||||
fetch(`${apiHost}/api/share?isPromptable=${isPromptable}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ conversation_id: conversationId }),
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res.status);
|
||||
@@ -44,6 +119,7 @@ export const ShareConversationModal = ({
|
||||
})
|
||||
.catch((err) => setStatus('failed'));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 z-30 flex h-screen w-screen items-center justify-center bg-gray-alpha bg-opacity-50 text-chinese-black dark:text-silver">
|
||||
<div className="relative w-11/12 rounded-2xl bg-white p-10 dark:bg-outer-space sm:w-[512px]">
|
||||
@@ -53,13 +129,52 @@ export const ShareConversationModal = ({
|
||||
<div className="flex flex-col gap-2">
|
||||
<h2 className="text-xl font-medium">{t('modals.shareConv.label')}</h2>
|
||||
<p className="text-sm">{t('modals.shareConv.note')}</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-lg">Allow users to prompt further</span>
|
||||
<label className=" cursor-pointer select-none items-center">
|
||||
<div className="relative">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={allowPrompt}
|
||||
onChange={togglePromptPermission}
|
||||
className="sr-only"
|
||||
/>
|
||||
<div
|
||||
className={`box block h-8 w-14 rounded-full border border-purple-30 ${
|
||||
allowPrompt
|
||||
? 'bg-purple-30 dark:bg-purple-30'
|
||||
: 'dark:bg-transparent'
|
||||
}`}
|
||||
></div>
|
||||
<div
|
||||
className={`absolute left-1 top-1 flex h-6 w-6 items-center justify-center rounded-full transition ${
|
||||
allowPrompt ? 'translate-x-full bg-silver' : 'bg-purple-30'
|
||||
}`}
|
||||
></div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
{allowPrompt && (
|
||||
<div className="my-4">
|
||||
<Dropdown
|
||||
placeholder={t('modals.createAPIKey.sourceDoc')}
|
||||
selectedValue={sourcePath}
|
||||
onSelect={(selection: { label: string; value: string }) =>
|
||||
setSourcePath(selection)
|
||||
}
|
||||
options={extractDocPaths(sourceDocs ?? [])}
|
||||
size="w-full"
|
||||
rounded="xl"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-baseline justify-between gap-2">
|
||||
<span className="no-scrollbar w-full overflow-x-auto whitespace-nowrap rounded-full border-2 p-3 shadow-inner">{`${domain}/share/${
|
||||
identifier ?? '....'
|
||||
}`}</span>
|
||||
<span className="no-scrollbar w-full overflow-x-auto whitespace-nowrap rounded-full border-2 py-3 px-4">
|
||||
{`${domain}/share/${identifier ?? '....'}`}
|
||||
</span>
|
||||
{status === 'fetched' ? (
|
||||
<button
|
||||
className="my-1 h-10 w-36 rounded-full border border-solid border-purple-30 p-2 text-sm text-purple-30 hover:bg-purple-30 hover:text-white"
|
||||
className="my-1 h-10 w-28 rounded-full border border-solid border-purple-30 p-2 text-sm text-purple-30 hover:bg-purple-30 hover:text-white"
|
||||
onClick={() => handleCopyKey(`${domain}/share/${identifier}`)}
|
||||
>
|
||||
{isCopied
|
||||
@@ -68,9 +183,9 @@ export const ShareConversationModal = ({
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
className="my-1 flex h-10 w-36 items-center justify-evenly rounded-full border border-solid border-purple-30 p-2 text-center text-sm font-normal text-purple-30 hover:bg-purple-30 hover:text-white"
|
||||
className="my-1 flex h-10 w-28 items-center justify-evenly rounded-full border border-solid border-purple-30 p-2 text-center text-sm font-normal text-purple-30 hover:bg-purple-30 hover:text-white"
|
||||
onClick={() => {
|
||||
shareCoversationPublicly(false);
|
||||
shareCoversationPublicly(allowPrompt);
|
||||
}}
|
||||
>
|
||||
{t('modals.shareConv.create')}
|
||||
|
||||
Reference in New Issue
Block a user