mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 16:43:16 +00:00
(sync:locales) with static content
This commit is contained in:
@@ -37,12 +37,14 @@ export default function Hero({
|
||||
<Fragment key={key}>
|
||||
<button
|
||||
onClick={() => handleQuestion({ question: demo.query })}
|
||||
className="w-full rounded-full border border-silver px-6 py-4 text-left hover:border-gray-4000 dark:hover:border-gray-3000 xl:min-w-[24vw]"
|
||||
className="w-full rounded-full border border-silver px-6 py-4 text-left hover:border-gray-4000 dark:hover:border-gray-3000 xl:min-w-[24vw] bg-white dark:bg-raisin-black focus:outline-none focus:ring-2 focus:ring-purple-taupe"
|
||||
>
|
||||
<p className="mb-1 font-semibold text-black dark:text-silver">
|
||||
<p className="mb-1 font-semibold text-black-1000 dark:text-bright-gray">
|
||||
{demo.header}
|
||||
</p>
|
||||
<span className="text-gray-400">{demo.query}</span>
|
||||
<span className="text-gray-700 dark:text-gray-300">
|
||||
{demo.query}
|
||||
</span>
|
||||
</button>
|
||||
</Fragment>
|
||||
),
|
||||
|
||||
@@ -21,11 +21,10 @@ import {
|
||||
handleAbort,
|
||||
} from './conversation/conversationSlice';
|
||||
import ConversationTile from './conversation/ConversationTile';
|
||||
import { useDarkTheme, useMediaQuery, useOutsideAlerter } from './hooks';
|
||||
import { useDarkTheme, useMediaQuery } from './hooks';
|
||||
import useDefaultDocument from './hooks/useDefaultDocument';
|
||||
import DeleteConvModal from './modals/DeleteConvModal';
|
||||
import { ActiveState, Doc } from './models/misc';
|
||||
import APIKeyModal from './preferences/APIKeyModal';
|
||||
import { getConversations, getDocs } from './preferences/preferenceApi';
|
||||
import {
|
||||
selectApiKeyStatus,
|
||||
@@ -68,8 +67,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
const [isDocsListOpen, setIsDocsListOpen] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const isApiKeySet = useSelector(selectApiKeyStatus);
|
||||
const [apiKeyModalState, setApiKeyModalState] =
|
||||
useState<ActiveState>('INACTIVE');
|
||||
|
||||
const [uploadModalState, setUploadModalState] =
|
||||
useState<ActiveState>('INACTIVE');
|
||||
@@ -192,12 +189,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
useOutsideAlerter(navRef, () => {
|
||||
if (isMobile && navOpen && apiKeyModalState === 'INACTIVE') {
|
||||
setNavOpen(false);
|
||||
setIsDocsListOpen(false);
|
||||
}
|
||||
}, [navOpen, isDocsListOpen, apiKeyModalState]);
|
||||
|
||||
/*
|
||||
Needed to fix bug where if mobile nav was closed and then window was resized to desktop, nav would still be closed but the button to open would be gone, as per #1 on issue #146
|
||||
@@ -220,7 +211,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={Expand}
|
||||
alt="menu toggle"
|
||||
alt="Toggle navigation menu"
|
||||
className={`${
|
||||
!navOpen ? 'rotate-180' : 'rotate-0'
|
||||
} m-auto transition-all duration-200`}
|
||||
@@ -234,7 +225,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={openNewChat}
|
||||
alt="open new chat icon"
|
||||
alt="Start new chat"
|
||||
className="cursor-pointer"
|
||||
/>
|
||||
</button>
|
||||
@@ -263,7 +254,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
}}
|
||||
>
|
||||
<a href="/" className="flex gap-1.5">
|
||||
<img className="mb-2 h-10" src={DocsGPT3} alt="" />
|
||||
<img className="mb-2 h-10" src={DocsGPT3} alt="DocsGPT Logo" />
|
||||
<p className="my-auto text-2xl font-semibold">DocsGPT</p>
|
||||
</a>
|
||||
</div>
|
||||
@@ -275,7 +266,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={Expand}
|
||||
alt="menu toggle"
|
||||
alt="Toggle navigation menu"
|
||||
className={`${
|
||||
!navOpen ? 'rotate-180' : 'rotate-0'
|
||||
} m-auto transition-all duration-200`}
|
||||
@@ -298,7 +289,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={Add}
|
||||
alt="new"
|
||||
alt="Create new chat"
|
||||
className="opacity-80 group-hover:opacity-100"
|
||||
/>
|
||||
<p className=" text-sm text-dove-gray group-hover:text-neutral-600 dark:text-chinese-silver dark:group-hover:text-bright-gray">
|
||||
@@ -314,7 +305,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
<img
|
||||
src={isDarkTheme ? SpinnerDark : Spinner}
|
||||
className="animate-spin cursor-pointer bg-transparent"
|
||||
alt="Loading..."
|
||||
alt="Loading conversations"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -365,6 +356,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
<img
|
||||
className="mt-2 h-9 w-9 hover:cursor-pointer"
|
||||
src={UploadIcon}
|
||||
alt="Upload document"
|
||||
onClick={() => {
|
||||
setUploadModalState('ACTIVE');
|
||||
if (isMobile) {
|
||||
@@ -392,7 +384,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={SettingGear}
|
||||
alt="icon"
|
||||
alt="Settings"
|
||||
className="ml-2 w-5 filter dark:invert"
|
||||
/>
|
||||
<p className="my-auto text-sm text-eerie-black dark:text-white">
|
||||
@@ -414,7 +406,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={Discord}
|
||||
alt="discord"
|
||||
alt="Join Discord community"
|
||||
className="m-2 w-6 self-center filter dark:invert"
|
||||
/>
|
||||
</NavLink>
|
||||
@@ -427,7 +419,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={Twitter}
|
||||
alt="x"
|
||||
alt="Follow us on Twitter"
|
||||
className="m-2 w-5 self-center filter dark:invert"
|
||||
/>
|
||||
</NavLink>
|
||||
@@ -440,7 +432,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={Github}
|
||||
alt="github"
|
||||
alt="View on GitHub"
|
||||
className="m-2 w-6 self-center filter dark:invert"
|
||||
/>
|
||||
</NavLink>
|
||||
@@ -457,18 +449,13 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
>
|
||||
<img
|
||||
src={Hamburger}
|
||||
alt="menu toggle"
|
||||
alt="Toggle mobile menu"
|
||||
className="w-7 filter dark:invert"
|
||||
/>
|
||||
</button>
|
||||
<div className="text-[#949494] font-medium text-[20px]">DocsGPT</div>
|
||||
</div>
|
||||
</div>
|
||||
<APIKeyModal
|
||||
modalState={apiKeyModalState}
|
||||
setModalState={setApiKeyModalState}
|
||||
isCancellable={isApiKeySet}
|
||||
/>
|
||||
<DeleteConvModal
|
||||
modalState={modalStateDeleteConv}
|
||||
setModalState={setModalStateDeleteConv}
|
||||
|
||||
@@ -59,7 +59,8 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
|
||||
<div className="md:hidden z-10">
|
||||
<button
|
||||
onClick={() => scrollTabs(-1)}
|
||||
className="flex h-6 w-6 items-center rounded-full justify-center transition-all hover:bg-gray-100"
|
||||
className="flex h-6 w-6 items-center rounded-full justify-center transition-all hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
aria-label="Scroll tabs left"
|
||||
>
|
||||
<img src={ArrowLeft} alt="left-arrow" className="h-3" />
|
||||
</button>
|
||||
@@ -67,16 +68,22 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="flex flex-nowrap overflow-x-auto no-scrollbar md:space-x-4 scroll-smooth snap-x"
|
||||
role="tablist"
|
||||
aria-label="Settings tabs"
|
||||
>
|
||||
{tabs.map((tab, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
className={`snap-start h-9 rounded-3xl px-4 font-bold hover:text-neutral-600 dark:hover:text-white/60 ${
|
||||
className={`snap-start h-9 rounded-3xl px-4 font-bold transition-colors ${
|
||||
activeTab === tab
|
||||
? 'bg-neutral-100 text-neutral-600 dark:bg-dark-charcoal dark:text-white/60'
|
||||
: 'text-gray-6000'
|
||||
? 'bg-neutral-200 text-neutral-900 dark:bg-dark-charcoal dark:text-white'
|
||||
: 'text-neutral-700 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-white'
|
||||
}`}
|
||||
role="tab"
|
||||
aria-selected={activeTab === tab}
|
||||
aria-controls={`${tab.toLowerCase()}-panel`}
|
||||
id={`${tab.toLowerCase()}-tab`}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
@@ -85,7 +92,8 @@ const SettingsBar = ({ setActiveTab, activeTab }: SettingsBarProps) => {
|
||||
<div className="md:hidden z-10">
|
||||
<button
|
||||
onClick={() => scrollTabs(1)}
|
||||
className="flex h-6 w-6 rounded-full items-center justify-center hover:bg-gray-100"
|
||||
className="flex h-6 w-6 rounded-full items-center justify-center hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
aria-label="Scroll tabs right"
|
||||
>
|
||||
<img src={ArrowRight} alt="right-arrow" className="h-3" />
|
||||
</button>
|
||||
|
||||
@@ -386,13 +386,19 @@ export default function Conversation() {
|
||||
{...getRootProps()}
|
||||
className="flex w-full items-center rounded-[40px] border border-silver bg-white dark:bg-raisin-black"
|
||||
>
|
||||
<input {...getInputProps()}></input>
|
||||
<label htmlFor="file-upload" className="sr-only">
|
||||
{t('modals.uploadDoc.label')}
|
||||
</label>
|
||||
<input {...getInputProps()} id="file-upload" />
|
||||
<label htmlFor="message-input" className="sr-only">
|
||||
{t('inputPlaceholder')}
|
||||
</label>
|
||||
<textarea
|
||||
id="inputbox"
|
||||
id="message-input"
|
||||
ref={inputRef}
|
||||
tabIndex={1}
|
||||
placeholder={t('inputPlaceholder')}
|
||||
className={`inputbox-style w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-full bg-transparent py-5 text-base leading-tight opacity-100 focus:outline-none dark:bg-transparent dark:text-bright-gray`}
|
||||
className={`inputbox-style w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-full bg-transparent py-5 text-base leading-tight opacity-100 focus:outline-none dark:bg-transparent dark:text-bright-gray dark:placeholder-bright-gray dark:placeholder-opacity-50`}
|
||||
onInput={handleInput}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey) {
|
||||
@@ -400,19 +406,27 @@ export default function Conversation() {
|
||||
handleQuestionSubmission();
|
||||
}
|
||||
}}
|
||||
aria-label={t('inputPlaceholder')}
|
||||
></textarea>
|
||||
{status === 'loading' ? (
|
||||
<img
|
||||
src={isDarkTheme ? SpinnerDark : Spinner}
|
||||
className="relative right-[38px] bottom-[24px] -mr-[30px] animate-spin cursor-pointer self-end bg-transparent"
|
||||
></img>
|
||||
alt={t('loading')}
|
||||
/>
|
||||
) : (
|
||||
<div className="mx-1 cursor-pointer rounded-full p-3 text-center hover:bg-gray-3000 dark:hover:bg-dark-charcoal">
|
||||
<img
|
||||
className="ml-[4px] h-6 w-6 text-white "
|
||||
<button
|
||||
onClick={() => handleQuestionSubmission()}
|
||||
src={isDarkTheme ? SendDark : Send}
|
||||
></img>
|
||||
aria-label={t('send')}
|
||||
className="flex items-center justify-center"
|
||||
>
|
||||
<img
|
||||
className="ml-[4px] h-6 w-6 text-white"
|
||||
src={isDarkTheme ? SendDark : Send}
|
||||
alt={t('send')}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
||||
import rehypeKatex from 'rehype-katex';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkMath from 'remark-math';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import DocsGPT3 from '../assets/cute_docsgpt3.svg';
|
||||
import Dislike from '../assets/dislike.svg?react';
|
||||
@@ -62,6 +63,7 @@ const ConversationBubble = forwardRef<
|
||||
},
|
||||
ref,
|
||||
) {
|
||||
const { t } = useTranslation();
|
||||
// const bubbleRef = useRef<HTMLDivElement | null>(null);
|
||||
const chunks = useSelector(selectChunks);
|
||||
const selectedDocs = useSelector(selectSelectedDocs);
|
||||
@@ -113,13 +115,13 @@ const ConversationBubble = forwardRef<
|
||||
{isEditClicked && (
|
||||
<div ref={editableQueryRef} className="w-[75%] flex flex-col">
|
||||
<textarea
|
||||
placeholder="Type the updated query..."
|
||||
placeholder={t('conversation.edit.placeholder')}
|
||||
onChange={(e) => {
|
||||
setEditInputBox(e.target.value);
|
||||
}}
|
||||
rows={1}
|
||||
value={editInputBox}
|
||||
className="ml-2 mr-12 text-[15px] resize-y h-12 min-h-max rounded-3xl p-3 no-scrollbar leading-relaxed dark:border-[0.5px] dark:border-white dark:bg-raisin-black dark:text-white px-[18px] border-[1.5px] border-black"
|
||||
className="ml-2 mr-12 text-[15px] resize-y h-12 min-h-max rounded-3xl p-3 no-scrollbar leading-relaxed dark:border-[0.5px] dark:border-white dark:bg-raisin-black dark:text-white px-[18px] border-[1.5px] border-black"
|
||||
/>
|
||||
<div
|
||||
className={`flex flex-row-reverse justify-end gap-1 mt-3 text-sm font-medium`}
|
||||
@@ -128,13 +130,13 @@ const ConversationBubble = forwardRef<
|
||||
className="rounded-full bg-[#CDB5FF] hover:bg-[#E1D3FF] py-[10px] px-[15px] text-purple-30 max-w-full whitespace-pre-wrap leading-none"
|
||||
onClick={() => handleEditClick()}
|
||||
>
|
||||
Update
|
||||
{t('conversation.edit.update')}
|
||||
</button>
|
||||
<button
|
||||
className="py-[10px] px-[15px] no-underline hover:underline text-purple-30 max-w-full whitespace-pre-wrap leading-normal"
|
||||
onClick={() => setIsEditClicked(false)}
|
||||
>
|
||||
Cancel
|
||||
{t('conversation.edit.cancel')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -185,12 +187,14 @@ const ConversationBubble = forwardRef<
|
||||
avatar={
|
||||
<img
|
||||
src={Sources}
|
||||
alt="Sources"
|
||||
alt={t('conversation.sources.title')}
|
||||
className="h-full w-full object-fill"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<p className="text-base font-semibold">Sources</p>
|
||||
<p className="text-base font-semibold">
|
||||
{t('conversation.sources.title')}
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2 lg:grid-cols-4">
|
||||
{Array.from({ length: 4 }).map((_, index) => (
|
||||
@@ -217,12 +221,14 @@ const ConversationBubble = forwardRef<
|
||||
avatar={
|
||||
<img
|
||||
src={Sources}
|
||||
alt="Sources"
|
||||
alt={t('conversation.sources.title')}
|
||||
className="h-full w-full object-fill"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<p className="text-base font-semibold">Sources</p>
|
||||
<p className="text-base font-semibold">
|
||||
{t('conversation.sources.title')}
|
||||
</p>
|
||||
</div>
|
||||
<div className="fade-in ml-3 mr-5 max-w-[90vw] md:max-w-[70vw] lg:max-w-[50vw]">
|
||||
<div className="grid grid-cols-2 gap-2 lg:grid-cols-4">
|
||||
@@ -289,9 +295,11 @@ const ConversationBubble = forwardRef<
|
||||
className="flex h-28 cursor-pointer flex-col-reverse rounded-[20px] bg-gray-1000 p-4 text-purple-30 hover:bg-[#F1F1F1] hover:text-[#6D3ECC] dark:bg-gun-metal dark:hover:bg-[#2C2E3C] dark:hover:text-[#8C67D7]"
|
||||
onClick={() => setIsSidebarOpen(true)}
|
||||
>
|
||||
<p className="ellipsis-text h-22 text-xs">{`View ${
|
||||
sources?.length ? sources.length - 3 : 0
|
||||
} more`}</p>
|
||||
<p className="ellipsis-text h-22 text-xs">
|
||||
{t('conversation.sources.view_more', {
|
||||
count: sources?.length ? sources.length - 3 : 0,
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -306,12 +314,14 @@ const ConversationBubble = forwardRef<
|
||||
avatar={
|
||||
<img
|
||||
src={DocsGPT3}
|
||||
alt="DocsGPT"
|
||||
alt={t('conversation.answer')}
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<p className="text-base font-semibold">Answer</p>
|
||||
<p className="text-base font-semibold">
|
||||
{t('conversation.answer')}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className={`fade-in-bubble ml-2 mr-5 flex max-w-[90vw] rounded-[28px] bg-gray-1000 py-[14px] px-7 dark:bg-gun-metal md:max-w-[70vw] lg:max-w-[50vw] ${
|
||||
@@ -419,7 +429,7 @@ const ConversationBubble = forwardRef<
|
||||
${type !== 'ERROR' ? 'group-hover:lg:visible' : 'hidden'}`}
|
||||
>
|
||||
<div>
|
||||
<SpeakButton text={message} /> {/* Add SpeakButton here */}
|
||||
<SpeakButton text={message} />
|
||||
</div>
|
||||
</div>
|
||||
{type === 'ERROR' && (
|
||||
@@ -557,7 +567,7 @@ function AllSources(sources: AllSourcesProps) {
|
||||
{source.source && source.source !== 'local' ? (
|
||||
<img
|
||||
src={Link}
|
||||
alt="Link"
|
||||
alt={'Link'}
|
||||
className="h-3 w-3 cursor-pointer object-fill"
|
||||
onClick={() =>
|
||||
window.open(source.source, '_blank', 'noopener, noreferrer')
|
||||
|
||||
@@ -115,6 +115,19 @@ export default function ConversationTile({
|
||||
setConversationsName(conversation.name);
|
||||
setIsEdit(false);
|
||||
}
|
||||
|
||||
const handleRenameKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
e.stopPropagation();
|
||||
if (e.key === 'Enter') {
|
||||
handleSaveConversation({
|
||||
id: conversation.id,
|
||||
name: conversationName,
|
||||
});
|
||||
} else if (e.key === 'Escape') {
|
||||
onClear();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
@@ -144,6 +157,7 @@ export default function ConversationTile({
|
||||
className="h-6 w-full bg-transparent px-1 text-sm font-normal leading-6 focus:outline-[#0075FF]"
|
||||
value={conversationName}
|
||||
onChange={(e) => setConversationsName(e.target.value)}
|
||||
onKeyDown={handleRenameKeyDown}
|
||||
/>
|
||||
) : (
|
||||
<p className="my-auto overflow-hidden overflow-ellipsis whitespace-nowrap text-sm font-normal leading-6 text-eerie-black dark:text-white">
|
||||
@@ -239,7 +253,7 @@ export default function ConversationTile({
|
||||
>
|
||||
<img
|
||||
src={Trash}
|
||||
alt="Edit"
|
||||
alt="Delete"
|
||||
width={24}
|
||||
height={24}
|
||||
className="cursor-pointer hover:opacity-50"
|
||||
|
||||
@@ -236,7 +236,7 @@ export const SharedConversation = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className=" flex w-11/12 flex-col items-center gap-4 pb-2 md:w-10/12 lg:w-6/12">
|
||||
<div className="flex w-11/12 flex-col items-center gap-4 pb-2 md:w-10/12 lg:w-6/12">
|
||||
{apiKey ? (
|
||||
<div className="flex h-full w-full items-center rounded-[40px] border border-silver bg-white py-1 dark:bg-raisin-black">
|
||||
<div
|
||||
@@ -272,7 +272,7 @@ export const SharedConversation = () => {
|
||||
) : (
|
||||
<button
|
||||
onClick={() => navigate('/')}
|
||||
className="w-fit rounded-full bg-purple-30 p-4 text-white shadow-xl transition-colors duration-200 hover:bg-purple-taupe"
|
||||
className="w-fit rounded-full bg-purple-30 p-4 text-white shadow-xl transition-colors duration-200 hover:bg-purple-taupe mb-14 sm:mb-0"
|
||||
>
|
||||
{t('sharedConv.button')}
|
||||
</button>
|
||||
|
||||
@@ -41,16 +41,16 @@
|
||||
"selectLanguage": "Select Language",
|
||||
"chunks": "Chunks processed per query",
|
||||
"prompt": "Active Prompt",
|
||||
"deleteAllLabel": "Delete all Conversation",
|
||||
"deleteAllBtn": "Delete all",
|
||||
"deleteAllLabel": "Delete All Conversations",
|
||||
"deleteAllBtn": "Delete All",
|
||||
"addNew": "Add New",
|
||||
"convHistory": "Conversational history",
|
||||
"convHistory": "Conversation History",
|
||||
"none": "None",
|
||||
"low": "Low",
|
||||
"medium": "Medium",
|
||||
"high": "High",
|
||||
"unlimited": "Unlimited",
|
||||
"default": "default"
|
||||
"default": "Default"
|
||||
},
|
||||
"documents": {
|
||||
"label": "Documents",
|
||||
@@ -58,7 +58,19 @@
|
||||
"date": "Vector Date",
|
||||
"type": "Type",
|
||||
"tokenUsage": "Token Usage",
|
||||
"noData": "No existing Documents"
|
||||
"noData": "No existing Documents",
|
||||
"searchPlaceholder": "Search...",
|
||||
"addNew": "Add New",
|
||||
"preLoaded": "Pre-loaded",
|
||||
"private": "Private",
|
||||
"sync": "Sync",
|
||||
"syncFrequency": {
|
||||
"never": "Never",
|
||||
"daily": "Daily",
|
||||
"weekly": "Weekly",
|
||||
"monthly": "Monthly"
|
||||
},
|
||||
"actions": "Actions"
|
||||
},
|
||||
"apiKeys": {
|
||||
"label": "Chatbots",
|
||||
@@ -126,11 +138,19 @@
|
||||
"secret": "Client Secret",
|
||||
"agent": "User agent",
|
||||
"searchQueries": "Search queries",
|
||||
"numberOfPosts": "Number of posts"
|
||||
"numberOfPosts": "Number of posts",
|
||||
"addQuery": "Add Query"
|
||||
},
|
||||
"drag": {
|
||||
"title": "Upload a source file",
|
||||
"description": "Drop your file here to add it as a source"
|
||||
},
|
||||
"progress": {
|
||||
"upload": "Upload is in progress",
|
||||
"training": "Training is in progress",
|
||||
"completed": "Training completed",
|
||||
"wait": "This may take several minutes",
|
||||
"tokenLimit": "Over the token limit, please consider uploading smaller document"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
@@ -195,5 +215,12 @@
|
||||
"previousPage": "Previous page",
|
||||
"nextPage": "Next page",
|
||||
"lastPage": "Last page"
|
||||
},
|
||||
"conversation": {
|
||||
"edit": {
|
||||
"update": "Update",
|
||||
"cancel": "Cancel",
|
||||
"placeholder": "Enter updated query..."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"language": "Spanish",
|
||||
"language": "Español",
|
||||
"chat": "Chat",
|
||||
"chats": "Chats",
|
||||
"newChat": "Nuevo Chat",
|
||||
@@ -8,7 +8,7 @@
|
||||
"inputPlaceholder": "Escribe tu mensaje aquí...",
|
||||
"tagline": "DocsGPT utiliza GenAI, por favor revisa información crítica utilizando fuentes.",
|
||||
"sourceDocs": "Fuente",
|
||||
"none": "Nada",
|
||||
"none": "Ninguno",
|
||||
"cancel": "Cancelar",
|
||||
"help": "Asistencia",
|
||||
"emailUs": "Envíanos un correo",
|
||||
@@ -36,29 +36,41 @@
|
||||
"general": {
|
||||
"label": "General",
|
||||
"selectTheme": "Seleccionar Tema",
|
||||
"light": "de luz",
|
||||
"dark": "oscura",
|
||||
"light": "Claro",
|
||||
"dark": "Oscuro",
|
||||
"selectLanguage": "Seleccionar Idioma",
|
||||
"chunks": "Trozos procesados por consulta",
|
||||
"chunks": "Fragmentos procesados por consulta",
|
||||
"prompt": "Prompt Activo",
|
||||
"deleteAllLabel": "Eliminar toda la Conversación",
|
||||
"deleteAllLabel": "Eliminar todas las conversaciones",
|
||||
"deleteAllBtn": "Eliminar todo",
|
||||
"addNew": "Agregar Nuevo",
|
||||
"convHistory": "Historia conversacional",
|
||||
"none": "ninguno",
|
||||
"convHistory": "Historial de conversaciones",
|
||||
"none": "Ninguno",
|
||||
"low": "Bajo",
|
||||
"medium": "Medio",
|
||||
"high": "Alto",
|
||||
"unlimited": "Ilimitado",
|
||||
"default": "predeterminada"
|
||||
"default": "Predeterminado"
|
||||
},
|
||||
"documents": {
|
||||
"label": "Documentos",
|
||||
"name": "Nombre del Documento",
|
||||
"date": "Fecha Vector",
|
||||
"date": "Fecha de Vector",
|
||||
"type": "Tipo",
|
||||
"tokenUsage": "Uso de Tokens",
|
||||
"noData": "No hay documentos existentes"
|
||||
"noData": "No hay documentos existentes",
|
||||
"searchPlaceholder": "Buscar...",
|
||||
"addNew": "Agregar Nuevo",
|
||||
"preLoaded": "Precargado",
|
||||
"private": "Privado",
|
||||
"sync": "Sincronizar",
|
||||
"syncFrequency": {
|
||||
"never": "Nunca",
|
||||
"daily": "Diario",
|
||||
"weekly": "Semanal",
|
||||
"monthly": "Mensual"
|
||||
},
|
||||
"actions": "Acciones"
|
||||
},
|
||||
"apiKeys": {
|
||||
"label": "Chatbots",
|
||||
@@ -95,21 +107,26 @@
|
||||
"tableHeader": "Conversaciones generadas por API / chatbot"
|
||||
},
|
||||
"tools": {
|
||||
"label": "Herramientas"
|
||||
"label": "Herramientas",
|
||||
"searchPlaceholder": "Buscar...",
|
||||
"addTool": "Agregar Herramienta",
|
||||
"noToolsAlt": "No se encontraron herramientas",
|
||||
"noToolsFound": "No se encontraron herramientas",
|
||||
"selectToolSetup": "Seleccione una herramienta para configurar"
|
||||
}
|
||||
},
|
||||
"modals": {
|
||||
"uploadDoc": {
|
||||
"label": "Subir nuevo documento",
|
||||
"select": "Elija cómo cargar su documento en DocsGPT",
|
||||
"select": "Elige cómo cargar tu documento en DocsGPT",
|
||||
"file": "Subir desde el dispositivo",
|
||||
"back": "Atrás",
|
||||
"wait": "Espere por favor ...",
|
||||
"wait": "Por favor espera ...",
|
||||
"remote": "Recoger desde un sitio web",
|
||||
"start": "Empezar a chatear",
|
||||
"start": "Comenzar a chatear",
|
||||
"name": "Nombre",
|
||||
"choose": "Seleccionar Archivos",
|
||||
"info": "Por favor, suba archivos .pdf, .txt, .rst, .csv, .xlsx, .docx, .md, .html, .epub, .json, .pptx, .zip limitados a 25 MB",
|
||||
"info": "Por favor, sube archivos .pdf, .txt, .rst, .csv, .xlsx, .docx, .md, .html, .epub, .json, .pptx, .zip limitados a 25MB",
|
||||
"uploadedFiles": "Archivos Subidos",
|
||||
"cancel": "Cancelar",
|
||||
"train": "Entrenar",
|
||||
@@ -117,39 +134,47 @@
|
||||
"urlLink": "Enlace URL",
|
||||
"repoUrl": "URL del Repositorio",
|
||||
"reddit": {
|
||||
"id": "ID de Cliente",
|
||||
"secret": "Secreto de Cliente",
|
||||
"agent": "Agente de Usuario",
|
||||
"searchQueries": "Consultas de Búsqueda",
|
||||
"numberOfPosts": "Número de publicaciones"
|
||||
"id": "ID del Cliente",
|
||||
"secret": "Secreto del Cliente",
|
||||
"agent": "Agente de usuario",
|
||||
"searchQueries": "Consultas de búsqueda",
|
||||
"numberOfPosts": "Número de publicaciones",
|
||||
"addQuery": "Agregar Consulta"
|
||||
},
|
||||
"drag": {
|
||||
"title": "Cargar un archivo fuente",
|
||||
"description": "Suelta tu archivo aquí para agregarlo como fuente."
|
||||
"title": "Subir archivo fuente",
|
||||
"description": "Arrastra tu archivo aquí para agregarlo como fuente"
|
||||
},
|
||||
"progress": {
|
||||
"upload": "Subida en progreso",
|
||||
"training": "Entrenamiento en progreso",
|
||||
"completed": "Entrenamiento completado",
|
||||
"wait": "Esto puede tardar varios minutos",
|
||||
"tokenLimit": "Excede el límite de tokens, considere cargar un documento más pequeño"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
"label": "Crear Nueva Clave de API",
|
||||
"apiKeyName": "Nombre de la Clave de API",
|
||||
"chunks": "Fragmentos procesados por consulta",
|
||||
"prompt": "Seleccione el prompt activo",
|
||||
"prompt": "Selecciona el prompt activo",
|
||||
"sourceDoc": "Documento Fuente",
|
||||
"create": "Crear"
|
||||
},
|
||||
"saveKey": {
|
||||
"note": "Por favor, guarde su Clave",
|
||||
"disclaimer": "Esta es la única vez que se mostrará su clave.",
|
||||
"note": "Por favor, guarda tu Clave",
|
||||
"disclaimer": "Esta es la única vez que se mostrará tu clave.",
|
||||
"copy": "Copiar",
|
||||
"copied": "Copiado",
|
||||
"confirm": "He guardado la Clave"
|
||||
},
|
||||
"deleteConv": {
|
||||
"confirm": "¿Está seguro de que desea eliminar todas las conversaciones?",
|
||||
"confirm": "¿Estás seguro de que deseas eliminar todas las conversaciones?",
|
||||
"delete": "Eliminar"
|
||||
},
|
||||
"shareConv": {
|
||||
"label": "Crear una página pública para compartir",
|
||||
"note": "El documento original, la información personal y las conversaciones posteriores permanecerán privadas",
|
||||
"note": "El documento fuente, información personal y conversaciones posteriores permanecerán privadas",
|
||||
"create": "Crear",
|
||||
"option": "Permitir a los usuarios realizar más consultas"
|
||||
},
|
||||
@@ -165,7 +190,7 @@
|
||||
"sharedConv": {
|
||||
"subtitle": "Creado con",
|
||||
"button": "Comienza con DocsGPT",
|
||||
"meta": "DocsGPT utiliza GenAI, por favor revise la información crítica utilizando fuentes."
|
||||
"meta": "DocsGPT utiliza GenAI, por favor revisa la información crítica utilizando fuentes."
|
||||
},
|
||||
"convTile": {
|
||||
"share": "Compartir",
|
||||
@@ -180,5 +205,23 @@
|
||||
"previousPage": "Página anterior",
|
||||
"nextPage": "Página siguiente",
|
||||
"lastPage": "Última página"
|
||||
},
|
||||
"conversation": {
|
||||
"copy": "Copiar",
|
||||
"copied": "Copiado",
|
||||
"speak": "Hablar",
|
||||
"answer": "Respuesta",
|
||||
"edit": {
|
||||
"update": "Actualizar",
|
||||
"cancel": "Cancelar",
|
||||
"placeholder": "Ingrese la consulta actualizada..."
|
||||
},
|
||||
"sources": {
|
||||
"title": "Fuentes",
|
||||
"text": "Texto fuente",
|
||||
"link": "Enlace fuente",
|
||||
"view_more": "Ver {{count}} más fuentes"
|
||||
},
|
||||
"retry": "Reintentar"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
},
|
||||
{
|
||||
"header": "学習支援",
|
||||
"query": "コンテキストに対する潜在的な質問を書いてください"
|
||||
"query": "このコンテンツに対する可能な質問を書いてください"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
@@ -58,7 +58,19 @@
|
||||
"date": "ベクトル日付",
|
||||
"type": "タイプ",
|
||||
"tokenUsage": "トークン使用量",
|
||||
"noData": "既存のドキュメントがありません"
|
||||
"noData": "既存のドキュメントがありません",
|
||||
"searchPlaceholder": "検索...",
|
||||
"addNew": "新規追加",
|
||||
"preLoaded": "プリロード済み",
|
||||
"private": "プライベート",
|
||||
"sync": "同期",
|
||||
"syncFrequency": {
|
||||
"never": "なし",
|
||||
"daily": "毎日",
|
||||
"weekly": "毎週",
|
||||
"monthly": "毎月"
|
||||
},
|
||||
"actions": "アクション"
|
||||
},
|
||||
"apiKeys": {
|
||||
"label": "APIキー",
|
||||
@@ -114,7 +126,7 @@
|
||||
"start": "チャットを開始する",
|
||||
"name": "名前",
|
||||
"choose": "ファイルを選択",
|
||||
"info": "25MBまでの.pdf, .txt, .rst, .csv, .xlsx, .docx, .md, .html, .epub, .json, .pptx, .zipファイルをアップロードしてください",
|
||||
"info": "25MBまでの.pdf、.txt、.rst、.csv、.xlsx、.docx、.md、.html、.epub、.json、.pptx、.zipファイルをアップロードしてください",
|
||||
"uploadedFiles": "アップロードされたファイル",
|
||||
"cancel": "キャンセル",
|
||||
"train": "トレーニング",
|
||||
@@ -126,11 +138,19 @@
|
||||
"secret": "クライアントシークレット",
|
||||
"agent": "ユーザーエージェント",
|
||||
"searchQueries": "検索クエリ",
|
||||
"numberOfPosts": "投稿数"
|
||||
"numberOfPosts": "投稿数",
|
||||
"addQuery": "クエリを追加"
|
||||
},
|
||||
"drag": {
|
||||
"title": "ソースファイルをアップロードする",
|
||||
"description": "ファイルをここにドロップしてソースとして追加します"
|
||||
"title": "ソースファイルをアップロード",
|
||||
"description": "ファイルをここにドロップしてソースとして追加してください"
|
||||
},
|
||||
"progress": {
|
||||
"upload": "アップロード中",
|
||||
"training": "トレーニング中",
|
||||
"completed": "トレーニング完了",
|
||||
"wait": "数分かかる場合があります",
|
||||
"tokenLimit": "トークン制限を超えています。より小さいドキュメントをアップロードしてください"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
@@ -195,5 +215,23 @@
|
||||
"previousPage": "前のページ",
|
||||
"nextPage": "次のページ",
|
||||
"lastPage": "最後のページ"
|
||||
},
|
||||
"conversation": {
|
||||
"copy": "コピー",
|
||||
"copied": "コピー済み",
|
||||
"speak": "読み上げ",
|
||||
"answer": "回答",
|
||||
"edit": {
|
||||
"update": "更新",
|
||||
"cancel": "キャンセル",
|
||||
"placeholder": "更新されたクエリを入力..."
|
||||
},
|
||||
"sources": {
|
||||
"title": "ソース",
|
||||
"text": "ソーステキスト",
|
||||
"link": "ソースリンク",
|
||||
"view_more": "さらに{{count}}個のソースを表示"
|
||||
},
|
||||
"retry": "再試行"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
},
|
||||
{
|
||||
"header": "Помощь в обучении",
|
||||
"query": "Написать потенциальные вопросы для контекста"
|
||||
"query": "Написать возможные вопросы для этого контента"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
@@ -58,7 +58,19 @@
|
||||
"date": "Дата вектора",
|
||||
"type": "Тип",
|
||||
"tokenUsage": "Использование токена",
|
||||
"noData": "Нет существующих документов"
|
||||
"noData": "Нет существующих документов",
|
||||
"searchPlaceholder": "Поиск...",
|
||||
"addNew": "добавить новый",
|
||||
"preLoaded": "Предзагруженный",
|
||||
"private": "Частный",
|
||||
"sync": "Синхронизация",
|
||||
"syncFrequency": {
|
||||
"never": "Никогда",
|
||||
"daily": "Ежедневно",
|
||||
"weekly": "Еженедельно",
|
||||
"monthly": "Ежемесячно"
|
||||
},
|
||||
"actions": "Действия"
|
||||
},
|
||||
"apiKeys": {
|
||||
"label": "API ключи",
|
||||
@@ -117,9 +129,9 @@
|
||||
"info": "Пожалуйста, загрузите файлы .pdf, .txt, .rst, .csv, .xlsx, .docx, .md, .html, .epub, .json, .pptx, .zip размером до 25 МБ",
|
||||
"uploadedFiles": "Загруженные файлы",
|
||||
"cancel": "Отмена",
|
||||
"train": "Обучение",
|
||||
"train": "Тренировка",
|
||||
"link": "Ссылка",
|
||||
"urlLink": "URL-ссылка",
|
||||
"urlLink": "URL ссылка",
|
||||
"repoUrl": "URL репозитория",
|
||||
"reddit": {
|
||||
"id": "ID клиента",
|
||||
@@ -131,6 +143,13 @@
|
||||
"drag": {
|
||||
"title": "Загрузить исходный файл",
|
||||
"description": "Перетащите файл сюда, чтобы добавить его как источник"
|
||||
},
|
||||
"progress": {
|
||||
"upload": "Идет загрузка",
|
||||
"training": "Идет обучение",
|
||||
"completed": "Обучение завершено",
|
||||
"wait": "Это может занять несколько минут",
|
||||
"tokenLimit": "Превышен лимит токенов, рассмотрите возможность загрузки документа меньшего размера"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
@@ -195,5 +214,23 @@
|
||||
"previousPage": "Предыдущая страница",
|
||||
"nextPage": "Следующая страница",
|
||||
"lastPage": "Последняя страница"
|
||||
},
|
||||
"conversation": {
|
||||
"copy": "Копировать",
|
||||
"copied": "Скопировано",
|
||||
"speak": "Озвучить",
|
||||
"answer": "Ответ",
|
||||
"edit": {
|
||||
"update": "Обновить",
|
||||
"cancel": "Отмена",
|
||||
"placeholder": "Введите обновленный запрос..."
|
||||
},
|
||||
"sources": {
|
||||
"title": "Источники",
|
||||
"text": "Текст источника",
|
||||
"link": "Ссылка на источник",
|
||||
"view_more": "Показать еще {{count}} источников"
|
||||
},
|
||||
"retry": "Повторить"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,19 @@
|
||||
"date": "向量日期",
|
||||
"type": "類型",
|
||||
"tokenUsage": "Token 使用量",
|
||||
"noData": "沒有現有的文件"
|
||||
"noData": "沒有現有的文件",
|
||||
"searchPlaceholder": "搜尋...",
|
||||
"addNew": "新增文件",
|
||||
"preLoaded": "預載入",
|
||||
"private": "私人",
|
||||
"sync": "同步",
|
||||
"syncFrequency": {
|
||||
"never": "從不",
|
||||
"daily": "每天",
|
||||
"weekly": "每週",
|
||||
"monthly": "每月"
|
||||
},
|
||||
"actions": "操作"
|
||||
},
|
||||
"apiKeys": {
|
||||
"label": "聊天機器人",
|
||||
@@ -114,23 +126,31 @@
|
||||
"start": "開始對話",
|
||||
"name": "名稱",
|
||||
"choose": "選擇檔案",
|
||||
"info": "請上傳 .pdf, .txt, .rst, .csv, .xlsx, .docx, .md, .html, .epub, .json, .pptx, .zip 檔案,大小限制為 25MB",
|
||||
"uploadedFiles": "已上傳的檔案",
|
||||
"info": "請上傳限制為25MB的.pdf、.txt、.rst、.csv、.xlsx、.docx、.md、.html、.epub、.json、.pptx、.zip檔案",
|
||||
"uploadedFiles": "已上傳檔案",
|
||||
"cancel": "取消",
|
||||
"train": "訓練",
|
||||
"link": "連結",
|
||||
"urlLink": "URL 連結",
|
||||
"repoUrl": "儲存庫 URL",
|
||||
"reddit": {
|
||||
"id": "用戶端 ID",
|
||||
"secret": "用戶端金鑰",
|
||||
"agent": "使用者代理(User-Agent)",
|
||||
"id": "客戶端ID",
|
||||
"secret": "客戶端密鑰",
|
||||
"agent": "使用者代理",
|
||||
"searchQueries": "搜尋查詢",
|
||||
"numberOfPosts": "貼文數量"
|
||||
"numberOfPosts": "貼文數量",
|
||||
"addQuery": "新增查詢"
|
||||
},
|
||||
"drag": {
|
||||
"title": "上傳原始檔",
|
||||
"description": "將您的文件拖放到此處以將其添加為來源"
|
||||
"title": "上傳來源檔案",
|
||||
"description": "將檔案拖放到此處以新增為來源"
|
||||
},
|
||||
"progress": {
|
||||
"upload": "正在上傳",
|
||||
"training": "正在訓練",
|
||||
"completed": "訓練完成",
|
||||
"wait": "這可能需要幾分鐘",
|
||||
"tokenLimit": "超出令牌限制,請考慮上傳較小的文檔"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"settings": {
|
||||
"label": "设置",
|
||||
"general": {
|
||||
"label": "般",
|
||||
"label": "一般",
|
||||
"selectTheme": "选择主题",
|
||||
"light": "浅色",
|
||||
"dark": "暗色",
|
||||
@@ -58,7 +58,18 @@
|
||||
"date": "向量日期",
|
||||
"type": "类型",
|
||||
"tokenUsage": "令牌使用",
|
||||
"noData": "没有现有的文档"
|
||||
"noData": "没有现有的文档",
|
||||
"searchPlaceholder": "搜索...",
|
||||
"addNew": "添加新文档",
|
||||
"preLoaded": "预加载",
|
||||
"private": "私有",
|
||||
"sync": "同步",
|
||||
"syncFrequency": {
|
||||
"never": "从不",
|
||||
"daily": "每天",
|
||||
"weekly": "每周",
|
||||
"monthly": "每月"
|
||||
}
|
||||
},
|
||||
"apiKeys": {
|
||||
"label": "聊天机器人",
|
||||
@@ -114,7 +125,7 @@
|
||||
"start": "开始聊天",
|
||||
"name": "名称",
|
||||
"choose": "选择文件",
|
||||
"info": "请上传 .pdf, .txt, .rst, .csv, .xlsx, .docx, .md, .html, .epub, .json, .pptx, .zip 文件,限 25MB",
|
||||
"info": "请上传限制为25MB的.pdf、.txt、.rst、.csv、.xlsx、.docx、.md、.html、.epub、.json、.pptx、.zip文件",
|
||||
"uploadedFiles": "已上传文件",
|
||||
"cancel": "取消",
|
||||
"train": "训练",
|
||||
@@ -122,15 +133,23 @@
|
||||
"urlLink": "URL 链接",
|
||||
"repoUrl": "存储库 URL",
|
||||
"reddit": {
|
||||
"id": "客户端 ID",
|
||||
"id": "客户端ID",
|
||||
"secret": "客户端密钥",
|
||||
"agent": "用户代理",
|
||||
"searchQueries": "搜索查询",
|
||||
"numberOfPosts": "帖子数量"
|
||||
"numberOfPosts": "帖子数量",
|
||||
"addQuery": "添加查询"
|
||||
},
|
||||
"drag": {
|
||||
"title": "上传源文件",
|
||||
"description": "将您的文件拖放到此处以将其添加为源"
|
||||
"description": "将文件拖放到此处以添加为源"
|
||||
},
|
||||
"progress": {
|
||||
"upload": "正在上传",
|
||||
"training": "正在训练",
|
||||
"completed": "训练完成",
|
||||
"wait": "这可能需要几分钟",
|
||||
"tokenLimit": "超出令牌限制,请考虑上传较小的文档"
|
||||
}
|
||||
},
|
||||
"createAPIKey": {
|
||||
@@ -195,5 +214,23 @@
|
||||
"previousPage": "上一页",
|
||||
"nextPage": "下一页",
|
||||
"lastPage": "最后一页"
|
||||
},
|
||||
"conversation": {
|
||||
"copy": "复制",
|
||||
"copied": "已复制",
|
||||
"speak": "朗读",
|
||||
"answer": "回答",
|
||||
"edit": {
|
||||
"update": "更新",
|
||||
"cancel": "取消",
|
||||
"placeholder": "输入更新的查询..."
|
||||
},
|
||||
"sources": {
|
||||
"title": "来源",
|
||||
"text": "来源文本",
|
||||
"link": "来源链接",
|
||||
"view_more": "更多{{count}}个来源"
|
||||
},
|
||||
"retry": "重试"
|
||||
}
|
||||
}
|
||||
|
||||
11
frontend/src/locale/zhTW.json
Normal file
11
frontend/src/locale/zhTW.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"modals": {
|
||||
"uploadDoc": {
|
||||
"progress": {
|
||||
"completed": "訓練完成",
|
||||
"wait": "這可能需要幾分鐘",
|
||||
"tokenLimit": "超出令牌限制,請考慮上傳較小的文檔"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
import React, { useRef } from 'react';
|
||||
import userService from '../api/services/userService';
|
||||
import Exit from '../assets/exit.svg';
|
||||
import { ActiveState } from '../models/misc';
|
||||
import { AvailableTool } from './types';
|
||||
import ConfigToolModal from './ConfigToolModal';
|
||||
import { useOutsideAlerter } from '../hooks';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function AddToolModal({
|
||||
message,
|
||||
@@ -25,6 +26,14 @@ export default function AddToolModal({
|
||||
);
|
||||
const [configModalState, setConfigModalState] =
|
||||
React.useState<ActiveState>('INACTIVE');
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
const { t } = useTranslation();
|
||||
|
||||
useOutsideAlerter(modalRef, () => {
|
||||
if (modalState === 'ACTIVE') {
|
||||
setModalState('INACTIVE');
|
||||
}
|
||||
}, [modalState]);
|
||||
|
||||
const getAvailableTools = () => {
|
||||
userService
|
||||
@@ -63,14 +72,18 @@ export default function AddToolModal({
|
||||
React.useEffect(() => {
|
||||
if (modalState === 'ACTIVE') getAvailableTools();
|
||||
}, [modalState]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={`${
|
||||
modalState === 'ACTIVE' ? 'visible' : 'hidden'
|
||||
} fixed top-0 left-0 z-30 h-screen w-screen bg-gray-alpha flex items-center justify-center`}
|
||||
} fixed top-0 left-0 z-30 h-screen w-screen bg-gray-alpha flex items-center justify-center`}
|
||||
>
|
||||
<article className="flex h-[85vh] w-[90vw] md:w-[75vw] flex-col gap-4 rounded-2xl bg-[#FBFBFB] shadow-lg dark:bg-[#26272E]">
|
||||
<article
|
||||
ref={modalRef}
|
||||
className="flex h-[85vh] w-[90vw] md:w-[75vw] flex-col gap-4 rounded-2xl bg-[#FBFBFB] shadow-lg dark:bg-[#26272E]"
|
||||
>
|
||||
<div className="relative">
|
||||
<button
|
||||
className="absolute top-3 right-4 m-2 w-3"
|
||||
@@ -78,11 +91,15 @@ export default function AddToolModal({
|
||||
setModalState('INACTIVE');
|
||||
}}
|
||||
>
|
||||
<img className="filter dark:invert" src={Exit} />
|
||||
<img
|
||||
className="filter dark:invert"
|
||||
src={Exit}
|
||||
alt={t('cancel')}
|
||||
/>
|
||||
</button>
|
||||
<div className="p-6">
|
||||
<h2 className="font-semibold text-xl text-jet dark:text-bright-gray px-3">
|
||||
Select a tool to set up
|
||||
{t('settings.tools.selectToolSetup')}
|
||||
</h2>
|
||||
<div className="mt-5 flex flex-col sm:grid sm:grid-cols-3 gap-4 h-[73vh] overflow-auto px-3 py-px">
|
||||
{availableTools.map((tool, index) => (
|
||||
|
||||
@@ -14,4 +14,5 @@ export type WrapperModalProps = {
|
||||
children?: React.ReactNode;
|
||||
isPerformingTask?: boolean;
|
||||
close: () => void;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
@@ -32,8 +32,9 @@ function AddPrompt({
|
||||
setNewPromptName('');
|
||||
setNewPromptContent('');
|
||||
}}
|
||||
aria-label="Close add prompt modal"
|
||||
>
|
||||
<img className="filter dark:invert" src={Exit} />
|
||||
<img className="filter dark:invert" src={Exit} alt="Close modal" />
|
||||
</button>
|
||||
<div className="p-8">
|
||||
<p className="mb-1 text-xl text-jet dark:text-bright-gray">
|
||||
@@ -43,6 +44,9 @@ function AddPrompt({
|
||||
{t('modals.prompts.addDescription')}
|
||||
</p>
|
||||
<div>
|
||||
<label htmlFor="new-prompt-name" className="sr-only">
|
||||
Prompt Name
|
||||
</label>
|
||||
<Input
|
||||
placeholder={t('modals.prompts.promptName')}
|
||||
type="text"
|
||||
@@ -60,10 +64,15 @@ function AddPrompt({
|
||||
{t('modals.prompts.promptText')}
|
||||
</span>
|
||||
</div>
|
||||
<label htmlFor="new-prompt-content" className="sr-only">
|
||||
Prompt Text
|
||||
</label>
|
||||
<textarea
|
||||
id="new-prompt-content"
|
||||
className="h-56 w-full rounded-lg border-2 border-silver px-3 py-2 outline-none dark:border-silver/40 dark:bg-transparent dark:text-white"
|
||||
value={newPromptContent}
|
||||
onChange={(e) => setNewPromptContent(e.target.value)}
|
||||
aria-label="Prompt Text"
|
||||
></textarea>
|
||||
</div>
|
||||
<div className="mt-6 flex flex-row-reverse">
|
||||
@@ -111,8 +120,9 @@ function EditPrompt({
|
||||
onClick={() => {
|
||||
setModalState('INACTIVE');
|
||||
}}
|
||||
aria-label="Close edit prompt modal"
|
||||
>
|
||||
<img className="filter dark:invert" src={Exit} />
|
||||
<img className="filter dark:invert" src={Exit} alt="Close modal" />
|
||||
</button>
|
||||
<div className="p-8">
|
||||
<p className="mb-1 text-xl text-jet dark:text-bright-gray">
|
||||
@@ -122,13 +132,16 @@ function EditPrompt({
|
||||
{t('modals.prompts.editDescription')}
|
||||
</p>
|
||||
<div>
|
||||
<label htmlFor="edit-prompt-name" className="sr-only">
|
||||
Prompt Name
|
||||
</label>
|
||||
<Input
|
||||
placeholder={t('modals.prompts.promptName')}
|
||||
type="text"
|
||||
className="h-10 rounded-lg"
|
||||
value={editPromptName}
|
||||
onChange={(e) => setEditPromptName(e.target.value)}
|
||||
></Input>
|
||||
/>
|
||||
<div className="relative bottom-12 left-3 mt-[-3.00px]">
|
||||
<span className="bg-white px-1 text-xs text-silver dark:bg-outer-space dark:text-silver">
|
||||
{t('modals.prompts.promptName')}
|
||||
@@ -139,10 +152,15 @@ function EditPrompt({
|
||||
{t('modals.prompts.promptText')}
|
||||
</span>
|
||||
</div>
|
||||
<label htmlFor="edit-prompt-content" className="sr-only">
|
||||
Prompt Text
|
||||
</label>
|
||||
<textarea
|
||||
id="edit-prompt-content"
|
||||
className="h-56 w-full rounded-lg border-2 border-silver px-3 py-2 outline-none dark:border-silver/40 dark:bg-transparent dark:text-white"
|
||||
value={editPromptContent}
|
||||
onChange={(e) => setEditPromptContent(e.target.value)}
|
||||
aria-label="Prompt Text"
|
||||
></textarea>
|
||||
</div>
|
||||
<div className="mt-6 flex flex-row-reverse gap-4">
|
||||
|
||||
@@ -115,12 +115,20 @@ export default function APIKeys() {
|
||||
<table className="min-w-full divide-y divide-silver dark:divide-silver/40 ">
|
||||
<thead>
|
||||
<tr className="text-start text-sm font-medium text-gray-700 dark:text-gray-50 uppercase">
|
||||
<th className="p-2">{t('settings.apiKeys.name')}</th>
|
||||
<th className="p-2">
|
||||
<th scope="col" className="p-2">
|
||||
{t('settings.apiKeys.name')}
|
||||
</th>
|
||||
<th scope="col" className="p-2">
|
||||
{t('settings.apiKeys.sourceDoc')}
|
||||
</th>
|
||||
<th className="p-2">{t('settings.apiKeys.key')}</th>
|
||||
<th></th>
|
||||
<th scope="col" className="p-2">
|
||||
{t('settings.apiKeys.key')}
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
className="p-2"
|
||||
aria-label="Actions"
|
||||
></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200 dark:divide-neutral-700">
|
||||
@@ -146,7 +154,7 @@ export default function APIKeys() {
|
||||
<td>
|
||||
<img
|
||||
src={Trash}
|
||||
alt="Delete"
|
||||
alt={`Delete ${element.name}`}
|
||||
className="h-4 w-4 cursor-pointer hover:opacity-50"
|
||||
id={`img-${index}`}
|
||||
onClick={() => handleDeleteKey(element.id)}
|
||||
|
||||
@@ -215,6 +215,7 @@ export default function Analytics() {
|
||||
}
|
||||
rounded="3xl"
|
||||
border="border"
|
||||
borderColor="gray-700"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -54,10 +54,10 @@ const Documents: React.FC<DocumentsProps> = ({
|
||||
const [totalPages, setTotalPages] = useState<number>(1);
|
||||
const currentDocuments = paginatedDocuments ?? [];
|
||||
const syncOptions = [
|
||||
{ label: 'Never', value: 'never' },
|
||||
{ label: 'Daily', value: 'daily' },
|
||||
{ label: 'Weekly', value: 'weekly' },
|
||||
{ label: 'Monthly', value: 'monthly' },
|
||||
{ label: t('settings.documents.syncFrequency.never'), value: 'never' },
|
||||
{ label: t('settings.documents.syncFrequency.daily'), value: 'daily' },
|
||||
{ label: t('settings.documents.syncFrequency.weekly'), value: 'weekly' },
|
||||
{ label: t('settings.documents.syncFrequency.monthly'), value: 'monthly' },
|
||||
];
|
||||
|
||||
const refreshDocs = useCallback(
|
||||
@@ -151,9 +151,12 @@ const Documents: React.FC<DocumentsProps> = ({
|
||||
<div className="z-10 w-full overflow-x-auto">
|
||||
<div className="my-3 flex justify-between items-center">
|
||||
<div className="p-1">
|
||||
<label htmlFor="document-search-input" className="sr-only">
|
||||
{t('settings.documents.searchPlaceholder')}
|
||||
</label>
|
||||
<Input
|
||||
maxLength={256}
|
||||
placeholder="Search..."
|
||||
placeholder={t('settings.documents.searchPlaceholder')}
|
||||
name="Document-search-input"
|
||||
type="text"
|
||||
id="document-search-input"
|
||||
@@ -161,21 +164,18 @@ const Documents: React.FC<DocumentsProps> = ({
|
||||
onChange={(e) => {
|
||||
setSearchTerm(e.target.value);
|
||||
setCurrentPage(1);
|
||||
// refreshDocs(sortField, 1, rowsPerPage);
|
||||
// do not call refreshDocs here the state is async
|
||||
// so it will not have the updated value
|
||||
}} // Handle search input change
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
className="rounded-full w-40 bg-purple-30 px-4 py-3 text-white hover:bg-[#6F3FD1]"
|
||||
title="Add New Document"
|
||||
title={t('settings.documents.addNew')}
|
||||
onClick={() => {
|
||||
setIsOnboarding(false); // Set onboarding flag if needed
|
||||
setModalState('ACTIVE'); // Open the upload modal
|
||||
setIsOnboarding(false);
|
||||
setModalState('ACTIVE');
|
||||
}}
|
||||
>
|
||||
Add New
|
||||
{t('settings.documents.addNew')}
|
||||
</button>
|
||||
</div>
|
||||
{loading ? (
|
||||
@@ -224,9 +224,10 @@ const Documents: React.FC<DocumentsProps> = ({
|
||||
*/}
|
||||
<th
|
||||
scope="col"
|
||||
className="px-6 py-2 text-start font-medium text-gray-700 dark:text-gray-50 uppercase"
|
||||
className="px-6 py-2 text-start font-medium text-gray-700 dark:text-gray-50 uppercase sr-only"
|
||||
aria-label={t('settings.documents.actions')}
|
||||
>
|
||||
{' '}
|
||||
{t('settings.documents.actions')}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -270,7 +271,7 @@ const Documents: React.FC<DocumentsProps> = ({
|
||||
{document.type !== 'remote' && (
|
||||
<img
|
||||
src={Trash}
|
||||
alt="Delete"
|
||||
alt={t('convTile.delete')}
|
||||
className="h-4 w-4 cursor-pointer opacity-60 hover:opacity-100"
|
||||
id={`img-${index}`}
|
||||
onClick={(event) => {
|
||||
@@ -282,7 +283,7 @@ const Documents: React.FC<DocumentsProps> = ({
|
||||
{document.syncFrequency && (
|
||||
<div className="ml-2">
|
||||
<DropdownMenu
|
||||
name="Sync"
|
||||
name={t('settings.documents.sync')}
|
||||
options={syncOptions}
|
||||
onSelect={(value: string) => {
|
||||
handleManageSync(document, value);
|
||||
|
||||
@@ -27,30 +27,12 @@ export default function General() {
|
||||
];
|
||||
|
||||
const languageOptions = [
|
||||
{
|
||||
label: 'English',
|
||||
value: 'en',
|
||||
},
|
||||
{
|
||||
label: 'Spanish',
|
||||
value: 'es',
|
||||
},
|
||||
{
|
||||
label: 'Japanese',
|
||||
value: 'jp',
|
||||
},
|
||||
{
|
||||
label: 'Mandarin',
|
||||
value: 'zh',
|
||||
},
|
||||
{
|
||||
label: 'Traditional Chinese',
|
||||
value: 'zhTW',
|
||||
},
|
||||
{
|
||||
label: 'Russian',
|
||||
value: 'ru',
|
||||
},
|
||||
{ label: 'English', value: 'en' },
|
||||
{ label: 'Español', value: 'es' },
|
||||
{ label: '日本語', value: 'jp' },
|
||||
{ label: '普通话', value: 'zh' },
|
||||
{ label: '繁體中文(臺灣)', value: 'zhTW' },
|
||||
{ label: 'Русский', value: 'ru' },
|
||||
];
|
||||
const chunks = ['0', '2', '4', '6', '8', '10'];
|
||||
const token_limits = new Map([
|
||||
@@ -102,9 +84,9 @@ export default function General() {
|
||||
return (
|
||||
<div className="mt-12">
|
||||
<div className="mb-5">
|
||||
<p className="font-bold text-jet dark:text-bright-gray">
|
||||
<label className="block font-bold text-jet dark:text-bright-gray">
|
||||
{t('settings.general.selectTheme')}
|
||||
</p>
|
||||
</label>
|
||||
<Dropdown
|
||||
options={themes}
|
||||
selectedValue={
|
||||
@@ -120,9 +102,9 @@ export default function General() {
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<p className="mb-2 font-bold text-jet dark:text-bright-gray">
|
||||
<label className="block mb-2 font-bold text-jet dark:text-bright-gray">
|
||||
{t('settings.general.selectLanguage')}
|
||||
</p>
|
||||
</label>
|
||||
<Dropdown
|
||||
options={languageOptions.filter(
|
||||
(languageOption) =>
|
||||
@@ -138,9 +120,9 @@ export default function General() {
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<p className="font-bold text-jet dark:text-bright-gray">
|
||||
<label className="block font-bold text-jet dark:text-bright-gray">
|
||||
{t('settings.general.chunks')}
|
||||
</p>
|
||||
</label>
|
||||
<Dropdown
|
||||
options={chunks}
|
||||
selectedValue={selectedChunks}
|
||||
@@ -151,9 +133,9 @@ export default function General() {
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-5">
|
||||
<p className="mb-2 font-bold text-jet dark:text-bright-gray">
|
||||
<label className="mb-2 block font-bold text-jet dark:text-bright-gray">
|
||||
{t('settings.general.convHistory')}
|
||||
</p>
|
||||
</label>
|
||||
<Dropdown
|
||||
options={Array.from(token_limits, ([value, desc]) => ({
|
||||
value: value,
|
||||
@@ -186,16 +168,14 @@ export default function General() {
|
||||
/>
|
||||
</div>
|
||||
<div className="w-56">
|
||||
<p className="font-bold text-jet dark:text-bright-gray">
|
||||
<label className="block font-bold text-jet dark:text-bright-gray">
|
||||
{t('settings.general.deleteAllLabel')}
|
||||
</p>
|
||||
</label>
|
||||
<button
|
||||
className="mt-2 flex w-full cursor-pointer items-center justify-between rounded-3xl border border-solid border-red-500 px-5 py-3 text-red-500 hover:bg-red-500 hover:text-white"
|
||||
className="mt-2 flex w-full cursor-pointer items-center justify-between rounded-3xl border border-solid border-red-700 px-5 py-3 text-red-700 transition-colors hover:bg-red-700 hover:text-white dark:border-red-600 dark:text-red-600 dark:hover:bg-red-600 dark:hover:text-white"
|
||||
onClick={() => dispatch(setModalStateDeleteConv('ACTIVE'))}
|
||||
>
|
||||
<span className="overflow-hidden text-ellipsis ">
|
||||
{t('settings.general.deleteAllBtn')}
|
||||
</span>
|
||||
{t('settings.general.deleteAllBtn')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -67,9 +67,12 @@ export default function Logs() {
|
||||
<div className="mt-12">
|
||||
<div className="flex flex-col items-start">
|
||||
<div className="flex flex-col gap-3">
|
||||
<p className="font-bold text-jet dark:text-bright-gray">
|
||||
<label
|
||||
id="chatbot-filter-label"
|
||||
className="font-bold text-jet dark:text-bright-gray"
|
||||
>
|
||||
{t('settings.logs.filterByChatbot')}
|
||||
</p>
|
||||
</label>
|
||||
{loadingChatbots ? (
|
||||
<SkeletonLoader />
|
||||
) : (
|
||||
|
||||
@@ -168,7 +168,7 @@ export default function Prompts({
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
className="mt-[24px] rounded-3xl border border-solid border-purple-30 px-5 py-3 text-purple-30 hover:bg-purple-30 hover:text-white"
|
||||
className="mt-[24px] rounded-3xl border border-solid border-purple-700 px-5 py-3 text-purple-700 transition-colors hover:bg-purple-700 hover:text-white dark:border-purple-400 dark:text-purple-400 dark:hover:bg-purple-400 dark:hover:text-white"
|
||||
onClick={() => {
|
||||
setModalType('ADD');
|
||||
setModalState('ACTIVE');
|
||||
|
||||
@@ -72,18 +72,21 @@ export default function Tools() {
|
||||
<div className="flex flex-col relative">
|
||||
<div className="my-3 flex justify-between items-center gap-1">
|
||||
<div className="p-1">
|
||||
<label htmlFor="tool-search-input" className="sr-only">
|
||||
{t('settings.tools.searchPlaceholder')}
|
||||
</label>
|
||||
<Input
|
||||
maxLength={256}
|
||||
placeholder={t('settings.tools.searchPlaceholder')}
|
||||
name="Document-search-input"
|
||||
type="text"
|
||||
id="document-search-input"
|
||||
id="tool-search-input"
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
className="rounded-full w-40 bg-purple-30 px-4 py-3 text-white hover:bg-[#6F3FD1] text-nowrap"
|
||||
className="rounded-full min-w-[160px] bg-purple-30 px-6 py-3 text-white hover:bg-[#6F3FD1] text-nowrap"
|
||||
onClick={() => {
|
||||
setAddToolModalState('ACTIVE');
|
||||
}}
|
||||
@@ -100,7 +103,7 @@ export default function Tools() {
|
||||
<div className="mt-24 col-span-2 lg:col-span-3 text-center text-gray-500 dark:text-gray-400">
|
||||
<img
|
||||
src={isDarkTheme ? NoFilesDarkIcon : NoFilesIcon}
|
||||
alt={t('settings.tools.noToolsAlt')}
|
||||
alt="No tools found"
|
||||
className="h-24 w-24 mx-auto mb-2"
|
||||
/>
|
||||
{t('settings.tools.noToolsFound')}
|
||||
@@ -121,15 +124,19 @@ export default function Tools() {
|
||||
<div className="w-full flex items-center justify-between">
|
||||
<img
|
||||
src={`/toolIcons/tool_${tool.name}.svg`}
|
||||
alt={`${tool.displayName} icon`}
|
||||
className="h-8 w-8"
|
||||
/>
|
||||
<button
|
||||
className="absolute top-3 right-3 cursor-pointer"
|
||||
onClick={() => handleSettingsClick(tool)}
|
||||
aria-label={t('settings.tools.configureToolAria', {
|
||||
toolName: tool.displayName,
|
||||
})}
|
||||
>
|
||||
<img
|
||||
src={CogwheelIcon}
|
||||
alt="settings"
|
||||
alt={t('settings.tools.settingsIconAlt')}
|
||||
className="h-[19px] w-[19px]"
|
||||
/>
|
||||
</button>
|
||||
@@ -148,6 +155,11 @@ export default function Tools() {
|
||||
htmlFor={`toolToggle-${index}`}
|
||||
className="relative inline-block h-6 w-10 cursor-pointer rounded-full bg-gray-300 dark:bg-[#D2D5DA33]/20 transition [-webkit-tap-highlight-color:_transparent] has-[:checked]:bg-[#0C9D35CC] has-[:checked]:dark:bg-[#0C9D35CC]"
|
||||
>
|
||||
<span className="sr-only">
|
||||
{t('settings.tools.toggleToolAria', {
|
||||
toolName: tool.displayName,
|
||||
})}
|
||||
</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
id={`toolToggle-${index}`}
|
||||
|
||||
@@ -91,8 +91,8 @@ export default function Settings() {
|
||||
case 'Widgets':
|
||||
return (
|
||||
<Widgets
|
||||
widgetScreenshot={widgetScreenshot} // Add this line
|
||||
onWidgetScreenshotChange={updateWidgetScreenshot} // Add this line
|
||||
widgetScreenshot={widgetScreenshot}
|
||||
onWidgetScreenshotChange={updateWidgetScreenshot}
|
||||
/>
|
||||
);
|
||||
case t('settings.apiKeys.label'):
|
||||
|
||||
@@ -54,11 +54,11 @@ function Upload({
|
||||
const setTimeoutRef = useRef<number | null>();
|
||||
|
||||
const urlOptions: { label: string; value: string }[] = [
|
||||
{ label: 'Crawler', value: 'crawler' },
|
||||
// { label: 'Sitemap', value: 'sitemap' },
|
||||
{ label: 'Link', value: 'url' },
|
||||
{ label: 'Reddit', value: 'reddit' },
|
||||
{ label: 'GitHub', value: 'github' }, // P3f93
|
||||
{ label: `Crawler`, value: 'crawler' },
|
||||
// { label: t('modals.uploadDoc.sitemap'), value: 'sitemap' },
|
||||
{ label: `Link`, value: 'url' },
|
||||
{ label: `GitHub`, value: 'github' },
|
||||
{ label: `Reddit`, value: 'reddit' },
|
||||
];
|
||||
|
||||
const [urlType, setUrlType] = useState<{ label: string; value: string }>({
|
||||
@@ -113,12 +113,14 @@ function Upload({
|
||||
<div className="mt-5 flex flex-col items-center gap-2 text-gray-2000 dark:text-bright-gray">
|
||||
<p className="text-gra text-xl tracking-[0.15px]">
|
||||
{isTraining &&
|
||||
(progress?.percentage === 100 ? 'Training completed' : title)}
|
||||
(progress?.percentage === 100
|
||||
? t('modals.uploadDoc.progress.completed')
|
||||
: title)}
|
||||
{!isTraining && title}
|
||||
</p>
|
||||
<p className="text-sm">This may take several minutes</p>
|
||||
<p className="text-sm">{t('modals.uploadDoc.progress.wait')}</p>
|
||||
<p className={`ml-5 text-xl text-red-400 ${isFailed ? '' : 'hidden'}`}>
|
||||
Over the token limit, please consider uploading smaller document
|
||||
{t('modals.uploadDoc.progress.tokenLimit')}
|
||||
</p>
|
||||
{/* <p className="mt-10 text-2xl">{progress?.percentage || 0}%</p> */}
|
||||
<ProgressBar progressPercent={progress?.percentage || 0} />
|
||||
@@ -148,7 +150,7 @@ function Upload({
|
||||
}
|
||||
|
||||
function UploadProgress() {
|
||||
return <Progress title="Upload is in progress"></Progress>;
|
||||
return <Progress title={t('modals.uploadDoc.progress.upload')}></Progress>;
|
||||
}
|
||||
|
||||
function TrainingProgress() {
|
||||
@@ -239,7 +241,7 @@ function Upload({
|
||||
}, [progress, dispatch]);
|
||||
return (
|
||||
<Progress
|
||||
title="Training is in progress"
|
||||
title={t('modals.uploadDoc.progress.training')}
|
||||
isCancellable={progress?.percentage === 100}
|
||||
isFailed={progress?.failed === true}
|
||||
isTraining={true}
|
||||
|
||||
Reference in New Issue
Block a user