mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-22 06:00:56 +02:00
🔍 feat: Show Messages from Search Result (#2699)
* refactor(Nav): delegate Search-specific variables/hooks to SearchContext * fix: safely determine firstTodayConvoId if convo is undefined * chore: remove empty line * feat: initial render of search messages * feat: SearchButtons * update Ko.ts * update localizations with new key phrases * chore: localization comparisons * fix: clear conversation state on searchQuery navigation * style: search messages view styling * refactor(Convo): consolidate logic to navigateWithLastTools from useNavigateToConvo * fix(SearchButtons): styling and correct navigation logic * fix(SearchBar): invalidate all message queries and invoke `clearText` if onChange value is empty * refactor(NewChat): consolidate new chat button logic to NewChatButtonIcon * chore: localizations for Nav date groups * chore: update comparisons * fix: early return from sendRequest to avoid quick searchQuery reset * style: Link Icon * chore: bump tiktoken, use o200k_base for gpt-4o
This commit is contained in:
parent
638ac5bba6
commit
e42709bd1f
36 changed files with 2742 additions and 234 deletions
|
@ -308,7 +308,7 @@ class OpenAIClient extends BaseClient {
|
||||||
let tokenizer;
|
let tokenizer;
|
||||||
this.encoding = 'text-davinci-003';
|
this.encoding = 'text-davinci-003';
|
||||||
if (this.isChatCompletion) {
|
if (this.isChatCompletion) {
|
||||||
this.encoding = 'cl100k_base';
|
this.encoding = this.modelOptions.model.includes('gpt-4o') ? 'o200k_base' : 'cl100k_base';
|
||||||
tokenizer = this.constructor.getTokenizer(this.encoding);
|
tokenizer = this.constructor.getTokenizer(this.encoding);
|
||||||
} else if (this.isUnofficialChatGptModel) {
|
} else if (this.isUnofficialChatGptModel) {
|
||||||
const extendSpecialTokens = {
|
const extendSpecialTokens = {
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
"pino": "^8.12.1",
|
"pino": "^8.12.1",
|
||||||
"sharp": "^0.32.6",
|
"sharp": "^0.32.6",
|
||||||
"tiktoken": "^1.0.10",
|
"tiktoken": "^1.0.15",
|
||||||
"traverse": "^0.6.7",
|
"traverse": "^0.6.7",
|
||||||
"ua-parser-js": "^1.0.36",
|
"ua-parser-js": "^1.0.36",
|
||||||
"winston": "^3.11.0",
|
"winston": "^3.11.0",
|
||||||
|
|
6
client/src/Providers/SearchContext.tsx
Normal file
6
client/src/Providers/SearchContext.tsx
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { createContext, useContext } from 'react';
|
||||||
|
import useSearch from '~/hooks/Conversations/useSearch';
|
||||||
|
type SearchContextType = ReturnType<typeof useSearch>;
|
||||||
|
|
||||||
|
export const SearchContext = createContext<SearchContextType>({} as SearchContextType);
|
||||||
|
export const useSearchContext = () => useContext(SearchContext);
|
|
@ -2,6 +2,7 @@ export { default as ToastProvider } from './ToastContext';
|
||||||
export { default as AssistantsProvider } from './AssistantsContext';
|
export { default as AssistantsProvider } from './AssistantsContext';
|
||||||
export * from './ChatContext';
|
export * from './ChatContext';
|
||||||
export * from './ToastContext';
|
export * from './ToastContext';
|
||||||
|
export * from './SearchContext';
|
||||||
export * from './FileMapContext';
|
export * from './FileMapContext';
|
||||||
export * from './AssistantsContext';
|
export * from './AssistantsContext';
|
||||||
export * from './AssistantsMapContext';
|
export * from './AssistantsMapContext';
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { Suspense } from 'react';
|
||||||
|
import type { TMessage, TMessageContentParts } from 'librechat-data-provider';
|
||||||
|
import { UnfinishedMessage } from './MessageContent';
|
||||||
|
import { DelayedRender } from '~/components/ui';
|
||||||
|
import MarkdownLite from './MarkdownLite';
|
||||||
|
import { cn } from '~/utils';
|
||||||
|
import Part from './Part';
|
||||||
|
|
||||||
|
const SearchContent = ({ message }: { message: TMessage }) => {
|
||||||
|
const { messageId } = message;
|
||||||
|
if (Array.isArray(message.content) && message.content.length > 0) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{message.content
|
||||||
|
.filter((part: TMessageContentParts | undefined) => part)
|
||||||
|
.map((part: TMessageContentParts | undefined, idx: number) => {
|
||||||
|
if (!part) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Part
|
||||||
|
key={`display-${messageId}-${idx}`}
|
||||||
|
showCursor={false}
|
||||||
|
isSubmitting={false}
|
||||||
|
part={part}
|
||||||
|
message={message}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{message.unfinished && (
|
||||||
|
<Suspense>
|
||||||
|
<DelayedRender delay={250}>
|
||||||
|
<UnfinishedMessage message={message} key={`unfinished-${messageId}`} />
|
||||||
|
</DelayedRender>
|
||||||
|
</Suspense>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'markdown prose dark:prose-invert light w-full break-words',
|
||||||
|
message.isCreatedByUser ? 'whitespace-pre-wrap dark:text-gray-20' : 'dark:text-gray-70',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<MarkdownLite content={message.text ?? ''} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SearchContent;
|
42
client/src/components/Chat/Messages/MinimalMessages.tsx
Normal file
42
client/src/components/Chat/Messages/MinimalMessages.tsx
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { cn } from '~/utils';
|
||||||
|
|
||||||
|
const MinimalMessages = React.forwardRef(
|
||||||
|
(
|
||||||
|
props: { children: React.ReactNode; className?: string },
|
||||||
|
ref: React.ForwardedRef<HTMLDivElement>,
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'relative flex w-full grow overflow-hidden bg-white dark:bg-gray-800',
|
||||||
|
props.className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="transition-width relative h-full w-full flex-1 overflow-auto bg-white dark:bg-gray-800">
|
||||||
|
<div className="flex h-full flex-col" role="presentation" tabIndex={0}>
|
||||||
|
<div className="flex-1 overflow-hidden overflow-y-auto">
|
||||||
|
<div className="dark:gpt-dark-gray relative h-full">
|
||||||
|
<div
|
||||||
|
ref={ref}
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
overflowY: 'auto',
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col pb-9 text-sm dark:bg-transparent">
|
||||||
|
{props.children}
|
||||||
|
<div className="dark:gpt-dark-gray group h-0 w-full flex-shrink-0 dark:border-gray-800/50" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export default MinimalMessages;
|
40
client/src/components/Chat/Messages/SearchButtons.tsx
Normal file
40
client/src/components/Chat/Messages/SearchButtons.tsx
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import { Link } from 'lucide-react';
|
||||||
|
import type { TMessage } from 'librechat-data-provider';
|
||||||
|
import { useLocalize, useNavigateToConvo } from '~/hooks';
|
||||||
|
import { useSearchContext } from '~/Providers';
|
||||||
|
import { getConversationById } from '~/utils';
|
||||||
|
|
||||||
|
export default function SearchButtons({ message }: { message: TMessage }) {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const { searchQueryRes } = useSearchContext();
|
||||||
|
const { navigateWithLastTools } = useNavigateToConvo();
|
||||||
|
|
||||||
|
if (!message.conversationId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const clickHandler = (event: React.MouseEvent<HTMLAnchorElement>) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const conversation = getConversationById(searchQueryRes?.data, message.conversationId);
|
||||||
|
if (!conversation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.title = message.title ?? '';
|
||||||
|
navigateWithLastTools(conversation);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="visible mt-0 flex items-center justify-center gap-1 self-end text-gray-400 lg:justify-start">
|
||||||
|
<a
|
||||||
|
className="ml-0 flex cursor-pointer items-center gap-1.5 rounded-md p-1 text-xs hover:text-gray-900 hover:underline dark:text-gray-400/70 dark:hover:text-gray-200 disabled:dark:hover:text-gray-400"
|
||||||
|
onClick={clickHandler}
|
||||||
|
title={localize('com_ui_go_to_conversation')}
|
||||||
|
>
|
||||||
|
<Link className="icon-sm" />
|
||||||
|
{message.title}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
61
client/src/components/Chat/Messages/SearchMessage.tsx
Normal file
61
client/src/components/Chat/Messages/SearchMessage.tsx
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
import { useAuthContext, useLocalize } from '~/hooks';
|
||||||
|
import type { TMessageProps } from '~/common';
|
||||||
|
import Icon from '~/components/Chat/Messages/MessageIcon';
|
||||||
|
import SearchContent from './Content/SearchContent';
|
||||||
|
import SearchButtons from './SearchButtons';
|
||||||
|
import SubRow from './SubRow';
|
||||||
|
import { cn } from '~/utils';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export default function Message({ message }: Pick<TMessageProps, 'message'>) {
|
||||||
|
const UsernameDisplay = useRecoilValue<boolean>(store.UsernameDisplay);
|
||||||
|
const { user } = useAuthContext();
|
||||||
|
const localize = useLocalize();
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { isCreatedByUser } = message ?? {};
|
||||||
|
|
||||||
|
let messageLabel = '';
|
||||||
|
if (isCreatedByUser) {
|
||||||
|
messageLabel = UsernameDisplay ? user?.name || user?.username : localize('com_user_message');
|
||||||
|
} else {
|
||||||
|
messageLabel = message.sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="text-token-text-primary w-full border-0 bg-transparent dark:border-0 dark:bg-transparent">
|
||||||
|
<div className="m-auto justify-center p-4 py-2 text-base md:gap-6 ">
|
||||||
|
<div className="final-completion group mx-auto flex flex-1 gap-3 text-base md:max-w-3xl md:px-5 lg:max-w-[40rem] lg:px-1 xl:max-w-[48rem] xl:px-5">
|
||||||
|
<div className="relative flex flex-shrink-0 flex-col items-end">
|
||||||
|
<div>
|
||||||
|
<div className="pt-0.5">
|
||||||
|
<div className="flex h-6 w-6 items-center justify-center overflow-hidden rounded-full">
|
||||||
|
<Icon message={message} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={cn('relative flex w-11/12 flex-col', isCreatedByUser ? '' : 'agent-turn')}
|
||||||
|
>
|
||||||
|
<div className="select-none font-semibold">{messageLabel}</div>
|
||||||
|
<div className="flex-col gap-1 md:gap-3">
|
||||||
|
<div className="flex max-w-full flex-grow flex-col gap-0">
|
||||||
|
<SearchContent message={message} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<SubRow classes="text-xs">
|
||||||
|
<SearchButtons message={message} />
|
||||||
|
</SubRow>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,22 +0,0 @@
|
||||||
import { memo } from 'react';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
import MessagesView from './Messages/MessagesView';
|
|
||||||
import store from '~/store';
|
|
||||||
|
|
||||||
import Header from './Header';
|
|
||||||
|
|
||||||
function SearchView() {
|
|
||||||
const searchResultMessagesTree = useRecoilValue(store.searchResultMessagesTree);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="relative flex w-full grow overflow-hidden bg-white dark:bg-gray-800">
|
|
||||||
<div className="transition-width relative flex h-full w-full flex-1 flex-col items-stretch overflow-hidden bg-white pt-0 dark:bg-gray-800">
|
|
||||||
<div className="flex h-full flex-col" role="presentation" tabIndex={0}>
|
|
||||||
<MessagesView messagesTree={searchResultMessagesTree} Header={<Header />} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(SearchView);
|
|
|
@ -2,6 +2,7 @@ import { useMemo, memo } from 'react';
|
||||||
import { parseISO, isToday } from 'date-fns';
|
import { parseISO, isToday } from 'date-fns';
|
||||||
import { TConversation } from 'librechat-data-provider';
|
import { TConversation } from 'librechat-data-provider';
|
||||||
import { groupConversationsByDate } from '~/utils';
|
import { groupConversationsByDate } from '~/utils';
|
||||||
|
import { useLocalize } from '~/hooks';
|
||||||
import Convo from './Convo';
|
import Convo from './Convo';
|
||||||
|
|
||||||
const Conversations = ({
|
const Conversations = ({
|
||||||
|
@ -13,12 +14,14 @@ const Conversations = ({
|
||||||
moveToTop: () => void;
|
moveToTop: () => void;
|
||||||
toggleNav: () => void;
|
toggleNav: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const localize = useLocalize();
|
||||||
const groupedConversations = useMemo(
|
const groupedConversations = useMemo(
|
||||||
() => groupConversationsByDate(conversations),
|
() => groupConversationsByDate(conversations),
|
||||||
[conversations],
|
[conversations],
|
||||||
);
|
);
|
||||||
const firstTodayConvoId = useMemo(
|
const firstTodayConvoId = useMemo(
|
||||||
() => conversations.find((convo) => isToday(parseISO(convo.updatedAt)))?.conversationId,
|
() =>
|
||||||
|
conversations.find((convo) => convo && isToday(parseISO(convo.updatedAt)))?.conversationId,
|
||||||
[conversations],
|
[conversations],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -37,7 +40,7 @@ const Conversations = ({
|
||||||
paddingLeft: '10px',
|
paddingLeft: '10px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{groupName}
|
{localize(groupName) || groupName}
|
||||||
</div>
|
</div>
|
||||||
{convos.map((convo, i) => (
|
{convos.map((convo, i) => (
|
||||||
<Convo
|
<Convo
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useState, useRef, useMemo } from 'react';
|
import { useState, useRef, useMemo } from 'react';
|
||||||
import { EModelEndpoint, LocalStorageKeys } from 'librechat-data-provider';
|
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
||||||
import type { MouseEvent, FocusEvent, KeyboardEvent } from 'react';
|
import type { MouseEvent, FocusEvent, KeyboardEvent } from 'react';
|
||||||
import { useUpdateConversationMutation } from '~/data-provider';
|
import { useUpdateConversationMutation } from '~/data-provider';
|
||||||
|
@ -26,8 +25,8 @@ export default function Conversation({ conversation, retainView, toggleNav, isLa
|
||||||
const updateConvoMutation = useUpdateConversationMutation(currentConvoId ?? '');
|
const updateConvoMutation = useUpdateConversationMutation(currentConvoId ?? '');
|
||||||
const activeConvos = useRecoilValue(store.allConversationsSelector);
|
const activeConvos = useRecoilValue(store.allConversationsSelector);
|
||||||
const { data: endpointsConfig } = useGetEndpointsQuery();
|
const { data: endpointsConfig } = useGetEndpointsQuery();
|
||||||
|
const { navigateWithLastTools } = useNavigateToConvo();
|
||||||
const { refreshConversations } = useConversations();
|
const { refreshConversations } = useConversations();
|
||||||
const { navigateToConvo } = useNavigateToConvo();
|
|
||||||
const { showToast } = useToastContext();
|
const { showToast } = useToastContext();
|
||||||
|
|
||||||
const { conversationId, title } = conversation;
|
const { conversationId, title } = conversation;
|
||||||
|
@ -51,23 +50,7 @@ export default function Conversation({ conversation, retainView, toggleNav, isLa
|
||||||
|
|
||||||
// set document title
|
// set document title
|
||||||
document.title = title;
|
document.title = title;
|
||||||
|
navigateWithLastTools(conversation);
|
||||||
// set conversation to the new conversation
|
|
||||||
if (conversation?.endpoint === EModelEndpoint.gptPlugins) {
|
|
||||||
let lastSelectedTools = [];
|
|
||||||
try {
|
|
||||||
lastSelectedTools =
|
|
||||||
JSON.parse(localStorage.getItem(LocalStorageKeys.LAST_TOOLS) ?? '') ?? [];
|
|
||||||
} catch (e) {
|
|
||||||
// console.error(e);
|
|
||||||
}
|
|
||||||
navigateToConvo({
|
|
||||||
...conversation,
|
|
||||||
tools: conversation?.tools?.length ? conversation?.tools : lastSelectedTools,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
navigateToConvo(conversation);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const renameHandler = (e: MouseEvent<HTMLButtonElement>) => {
|
const renameHandler = (e: MouseEvent<HTMLButtonElement>) => {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useCallback, useEffect, useState, useMemo, memo } from 'react';
|
import { useCallback, useEffect, useState, useMemo, memo } from 'react';
|
||||||
import type { ConversationListResponse } from 'librechat-data-provider';
|
|
||||||
import {
|
import {
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
useAuthContext,
|
useAuthContext,
|
||||||
|
@ -10,9 +9,10 @@ import {
|
||||||
useNavScrolling,
|
useNavScrolling,
|
||||||
useConversations,
|
useConversations,
|
||||||
} from '~/hooks';
|
} from '~/hooks';
|
||||||
import { useSearchInfiniteQuery, useConversationsInfiniteQuery } from '~/data-provider';
|
import { useConversationsInfiniteQuery } from '~/data-provider';
|
||||||
import { TooltipProvider, Tooltip } from '~/components/ui';
|
import { TooltipProvider, Tooltip } from '~/components/ui';
|
||||||
import { Conversations } from '~/components/Conversations';
|
import { Conversations } from '~/components/Conversations';
|
||||||
|
import { useSearchContext } from '~/Providers';
|
||||||
import { Spinner } from '~/components/svg';
|
import { Spinner } from '~/components/svg';
|
||||||
import SearchBar from './SearchBar';
|
import SearchBar from './SearchBar';
|
||||||
import NavToggle from './NavToggle';
|
import NavToggle from './NavToggle';
|
||||||
|
@ -47,26 +47,18 @@ const Nav = ({ navVisible, setNavVisible }) => {
|
||||||
}
|
}
|
||||||
}, [isSmallScreen]);
|
}, [isSmallScreen]);
|
||||||
|
|
||||||
const [pageNumber, setPageNumber] = useState(1);
|
const { newConversation } = useConversation();
|
||||||
const [showLoading, setShowLoading] = useState(false);
|
const [showLoading, setShowLoading] = useState(false);
|
||||||
|
|
||||||
const searchQuery = useRecoilValue(store.searchQuery);
|
|
||||||
const isSearchEnabled = useRecoilValue(store.isSearchEnabled);
|
const isSearchEnabled = useRecoilValue(store.isSearchEnabled);
|
||||||
const { newConversation, searchPlaceholderConversation } = useConversation();
|
|
||||||
|
|
||||||
const { refreshConversations } = useConversations();
|
const { refreshConversations } = useConversations();
|
||||||
const setSearchResultMessages = useSetRecoilState(store.searchResultMessages);
|
const { pageNumber, searchQuery, setPageNumber, searchQueryRes } = useSearchContext();
|
||||||
|
|
||||||
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useConversationsInfiniteQuery(
|
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useConversationsInfiniteQuery(
|
||||||
{ pageNumber: pageNumber.toString(), isArchived: false },
|
{ pageNumber: pageNumber.toString(), isArchived: false },
|
||||||
{ enabled: isAuthenticated },
|
{ enabled: isAuthenticated },
|
||||||
);
|
);
|
||||||
|
|
||||||
const searchQueryRes = useSearchInfiniteQuery(
|
|
||||||
{ pageNumber: pageNumber.toString(), searchQuery: searchQuery, isArchived: false },
|
|
||||||
{ enabled: isAuthenticated && !!searchQuery.length },
|
|
||||||
);
|
|
||||||
|
|
||||||
const { containerRef, moveToTop } = useNavScrolling({
|
const { containerRef, moveToTop } = useNavScrolling({
|
||||||
setShowLoading,
|
setShowLoading,
|
||||||
hasNextPage: searchQuery ? searchQueryRes.hasNextPage : hasNextPage,
|
hasNextPage: searchQuery ? searchQueryRes.hasNextPage : hasNextPage,
|
||||||
|
@ -81,21 +73,6 @@ const Nav = ({ navVisible, setNavVisible }) => {
|
||||||
[data, searchQuery, searchQueryRes?.data],
|
[data, searchQuery, searchQueryRes?.data],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onSearchSuccess = useCallback(({ data }: { data: ConversationListResponse }) => {
|
|
||||||
const res = data;
|
|
||||||
searchPlaceholderConversation();
|
|
||||||
setSearchResultMessages(res.messages);
|
|
||||||
/* disabled due recoil methods not recognized as state setters */
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []); // Empty dependency array
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
//we use isInitialLoading here instead of isLoading because query is disabled by default
|
|
||||||
if (searchQueryRes.data) {
|
|
||||||
onSearchSuccess({ data: searchQueryRes.data.pages[0] });
|
|
||||||
}
|
|
||||||
}, [searchQueryRes.data, searchQueryRes.isInitialLoading, onSearchSuccess]);
|
|
||||||
|
|
||||||
const clearSearch = () => {
|
const clearSearch = () => {
|
||||||
setPageNumber(1);
|
setPageNumber(1);
|
||||||
refreshConversations();
|
refreshConversations();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { Search } from 'lucide-react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
|
||||||
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
|
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
|
||||||
|
@ -7,6 +9,50 @@ import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
|
||||||
import { useLocalize, useNewConvo } from '~/hooks';
|
import { useLocalize, useNewConvo } from '~/hooks';
|
||||||
import { NewChatIcon } from '~/components/svg';
|
import { NewChatIcon } from '~/components/svg';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
import type { TConversation } from 'librechat-data-provider';
|
||||||
|
|
||||||
|
const NewChatButtonIcon = ({ conversation }: { conversation: TConversation | null }) => {
|
||||||
|
const searchQuery = useRecoilValue(store.searchQuery);
|
||||||
|
const { data: endpointsConfig } = useGetEndpointsQuery();
|
||||||
|
|
||||||
|
if (searchQuery) {
|
||||||
|
return (
|
||||||
|
<div className="shadow-stroke relative flex h-7 w-7 items-center justify-center rounded-full bg-white text-black dark:bg-white">
|
||||||
|
<Search className="h-5 w-5" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let { endpoint = '' } = conversation ?? {};
|
||||||
|
const iconURL = conversation?.iconURL ?? '';
|
||||||
|
endpoint = getIconEndpoint({ endpointsConfig, iconURL, endpoint });
|
||||||
|
|
||||||
|
const endpointType = getEndpointField(endpointsConfig, endpoint, 'type');
|
||||||
|
const endpointIconURL = getEndpointField(endpointsConfig, endpoint, 'iconURL');
|
||||||
|
const iconKey = getIconKey({ endpoint, endpointsConfig, endpointType, endpointIconURL });
|
||||||
|
const Icon = icons[iconKey];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="h-7 w-7 flex-shrink-0">
|
||||||
|
{iconURL && iconURL.includes('http') ? (
|
||||||
|
<ConvoIconURL preset={conversation} endpointIconURL={iconURL} context="nav" />
|
||||||
|
) : (
|
||||||
|
<div className="shadow-stroke relative flex h-full items-center justify-center rounded-full bg-white text-black dark:bg-white">
|
||||||
|
{endpoint &&
|
||||||
|
Icon &&
|
||||||
|
Icon({
|
||||||
|
size: 41,
|
||||||
|
context: 'nav',
|
||||||
|
className: 'h-2/3 w-2/3',
|
||||||
|
endpoint,
|
||||||
|
endpointType,
|
||||||
|
iconURL: endpointIconURL,
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default function NewChat({
|
export default function NewChat({
|
||||||
index = 0,
|
index = 0,
|
||||||
|
@ -22,16 +68,7 @@ export default function NewChat({
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
|
||||||
const { data: endpointsConfig } = useGetEndpointsQuery();
|
|
||||||
const { conversation } = store.useCreateConversationAtom(index);
|
const { conversation } = store.useCreateConversationAtom(index);
|
||||||
let { endpoint = '' } = conversation ?? {};
|
|
||||||
const iconURL = conversation?.iconURL ?? '';
|
|
||||||
endpoint = getIconEndpoint({ endpointsConfig, iconURL, endpoint });
|
|
||||||
|
|
||||||
const endpointType = getEndpointField(endpointsConfig, endpoint, 'type');
|
|
||||||
const endpointIconURL = getEndpointField(endpointsConfig, endpoint, 'iconURL');
|
|
||||||
const iconKey = getIconKey({ endpoint, endpointsConfig, endpointType, endpointIconURL });
|
|
||||||
const Icon = icons[iconKey];
|
|
||||||
|
|
||||||
const clickHandler = (event: React.MouseEvent<HTMLAnchorElement>) => {
|
const clickHandler = (event: React.MouseEvent<HTMLAnchorElement>) => {
|
||||||
if (event.button === 0 && !event.ctrlKey) {
|
if (event.button === 0 && !event.ctrlKey) {
|
||||||
|
@ -53,24 +90,7 @@ export default function NewChat({
|
||||||
onClick={clickHandler}
|
onClick={clickHandler}
|
||||||
className="group flex h-10 items-center gap-2 rounded-lg px-2 font-medium hover:bg-gray-200 dark:hover:bg-gray-700"
|
className="group flex h-10 items-center gap-2 rounded-lg px-2 font-medium hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||||
>
|
>
|
||||||
<div className="h-7 w-7 flex-shrink-0">
|
<NewChatButtonIcon conversation={conversation} />
|
||||||
{iconURL && iconURL.includes('http') ? (
|
|
||||||
<ConvoIconURL preset={conversation} endpointIconURL={iconURL} context="nav" />
|
|
||||||
) : (
|
|
||||||
<div className="shadow-stroke relative flex h-full items-center justify-center rounded-full bg-white text-black dark:bg-white">
|
|
||||||
{endpoint &&
|
|
||||||
Icon &&
|
|
||||||
Icon({
|
|
||||||
size: 41,
|
|
||||||
context: 'nav',
|
|
||||||
className: 'h-2/3 w-2/3',
|
|
||||||
endpoint,
|
|
||||||
endpointType,
|
|
||||||
iconURL: endpointIconURL,
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="text-token-text-primary grow overflow-hidden text-ellipsis whitespace-nowrap text-sm">
|
<div className="text-token-text-primary grow overflow-hidden text-ellipsis whitespace-nowrap text-sm">
|
||||||
{localize('com_ui_new_chat')}
|
{localize('com_ui_new_chat')}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { forwardRef, useState, useCallback, useMemo, Ref } from 'react';
|
import debounce from 'lodash/debounce';
|
||||||
import { Search, X } from 'lucide-react';
|
import { Search, X } from 'lucide-react';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
import debounce from 'lodash/debounce';
|
import { QueryKeys } from 'librechat-data-provider';
|
||||||
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { forwardRef, useState, useCallback, useMemo, Ref } from 'react';
|
||||||
import { useLocalize } from '~/hooks';
|
import { useLocalize } from '~/hooks';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
@ -12,6 +14,8 @@ type SearchBarProps = {
|
||||||
|
|
||||||
const SearchBar = forwardRef((props: SearchBarProps, ref: Ref<HTMLDivElement>) => {
|
const SearchBar = forwardRef((props: SearchBarProps, ref: Ref<HTMLDivElement>) => {
|
||||||
const { clearSearch } = props;
|
const { clearSearch } = props;
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const clearConvoState = store.useClearConvoState();
|
||||||
const setSearchQuery = useSetRecoilState(store.searchQuery);
|
const setSearchQuery = useSetRecoilState(store.searchQuery);
|
||||||
const [showClearIcon, setShowClearIcon] = useState(false);
|
const [showClearIcon, setShowClearIcon] = useState(false);
|
||||||
const [text, setText] = useState('');
|
const [text, setText] = useState('');
|
||||||
|
@ -31,7 +35,17 @@ const SearchBar = forwardRef((props: SearchBarProps, ref: Ref<HTMLDivElement>) =
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendRequest = useCallback((value: string) => setSearchQuery(value), [setSearchQuery]);
|
const sendRequest = useCallback(
|
||||||
|
(value: string) => {
|
||||||
|
setSearchQuery(value);
|
||||||
|
if (!value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
queryClient.invalidateQueries([QueryKeys.messages]);
|
||||||
|
clearConvoState();
|
||||||
|
},
|
||||||
|
[queryClient, clearConvoState, setSearchQuery],
|
||||||
|
);
|
||||||
const debouncedSendRequest = useMemo(() => debounce(sendRequest, 350), [sendRequest]);
|
const debouncedSendRequest = useMemo(() => debounce(sendRequest, 350), [sendRequest]);
|
||||||
|
|
||||||
const onChange = (e: React.FormEvent<HTMLInputElement>) => {
|
const onChange = (e: React.FormEvent<HTMLInputElement>) => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
export { default as useSearch } from './useSearch';
|
||||||
export { default as usePresets } from './usePresets';
|
export { default as usePresets } from './usePresets';
|
||||||
export { default as useGetSender } from './useGetSender';
|
export { default as useGetSender } from './useGetSender';
|
||||||
export { default as useDefaultConvo } from './useDefaultConvo';
|
export { default as useDefaultConvo } from './useDefaultConvo';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { useSetRecoilState, useResetRecoilState } from 'recoil';
|
import { useSetRecoilState, useResetRecoilState } from 'recoil';
|
||||||
import { QueryKeys } from 'librechat-data-provider';
|
import { QueryKeys, EModelEndpoint, LocalStorageKeys } from 'librechat-data-provider';
|
||||||
import type { TConversation, TEndpointsConfig, TModelsConfig } from 'librechat-data-provider';
|
import type { TConversation, TEndpointsConfig, TModelsConfig } from 'librechat-data-provider';
|
||||||
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField } from '~/utils';
|
import { buildDefaultConvo, getDefaultEndpoint, getEndpointField } from '~/utils';
|
||||||
import useOriginNavigate from '../useOriginNavigate';
|
import useOriginNavigate from '../useOriginNavigate';
|
||||||
|
@ -51,8 +51,28 @@ const useNavigateToConvo = (index = 0) => {
|
||||||
navigate(convo?.conversationId);
|
navigate(convo?.conversationId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const navigateWithLastTools = (conversation: TConversation) => {
|
||||||
|
// set conversation to the new conversation
|
||||||
|
if (conversation?.endpoint === EModelEndpoint.gptPlugins) {
|
||||||
|
let lastSelectedTools = [];
|
||||||
|
try {
|
||||||
|
lastSelectedTools =
|
||||||
|
JSON.parse(localStorage.getItem(LocalStorageKeys.LAST_TOOLS) ?? '') ?? [];
|
||||||
|
} catch (e) {
|
||||||
|
// console.error(e);
|
||||||
|
}
|
||||||
|
navigateToConvo({
|
||||||
|
...conversation,
|
||||||
|
tools: conversation?.tools?.length ? conversation?.tools : lastSelectedTools,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
navigateToConvo(conversation);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
navigateToConvo,
|
navigateToConvo,
|
||||||
|
navigateWithLastTools,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
69
client/src/hooks/Conversations/useSearch.ts
Normal file
69
client/src/hooks/Conversations/useSearch.ts
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
|
import { useGetSearchEnabledQuery } from 'librechat-data-provider/react-query';
|
||||||
|
import { useSearchInfiniteQuery } from '~/data-provider';
|
||||||
|
import useConversation from './useConversation';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export default function useSearchMessages({ isAuthenticated }: { isAuthenticated: boolean }) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const location = useLocation();
|
||||||
|
const [pageNumber, setPageNumber] = useState(1);
|
||||||
|
const { searchPlaceholderConversation } = useConversation();
|
||||||
|
|
||||||
|
const searchQuery = useRecoilValue(store.searchQuery);
|
||||||
|
const setIsSearchEnabled = useSetRecoilState(store.isSearchEnabled);
|
||||||
|
|
||||||
|
const searchEnabledQuery = useGetSearchEnabledQuery({ enabled: isAuthenticated });
|
||||||
|
const searchQueryRes = useSearchInfiniteQuery(
|
||||||
|
{ pageNumber: pageNumber.toString(), searchQuery: searchQuery, isArchived: false },
|
||||||
|
{ enabled: isAuthenticated && !!searchQuery.length },
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (searchQuery && searchQuery.length > 0) {
|
||||||
|
navigate('/search', { replace: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (location.pathname && location.pathname.includes('/c/')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
navigate('/c/new', { replace: true });
|
||||||
|
/* Disabled eslint rule because we don't want to run this effect when location changes */
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [navigate, searchQuery]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (searchEnabledQuery.data) {
|
||||||
|
setIsSearchEnabled(searchEnabledQuery.data);
|
||||||
|
} else if (searchEnabledQuery.isError) {
|
||||||
|
console.error('Failed to get search enabled', searchEnabledQuery.error);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
searchEnabledQuery.data,
|
||||||
|
searchEnabledQuery.error,
|
||||||
|
searchEnabledQuery.isError,
|
||||||
|
setIsSearchEnabled,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const onSearchSuccess = useCallback(
|
||||||
|
() => searchPlaceholderConversation(),
|
||||||
|
[searchPlaceholderConversation],
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
//we use isInitialLoading here instead of isLoading because query is disabled by default
|
||||||
|
if (searchQueryRes.data) {
|
||||||
|
onSearchSuccess();
|
||||||
|
}
|
||||||
|
}, [searchQueryRes.data, searchQueryRes.isInitialLoading, onSearchSuccess]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
pageNumber,
|
||||||
|
searchQuery,
|
||||||
|
setPageNumber,
|
||||||
|
searchQueryRes,
|
||||||
|
};
|
||||||
|
}
|
|
@ -280,6 +280,24 @@ export default {
|
||||||
com_nav_setting_general: 'عام',
|
com_nav_setting_general: 'عام',
|
||||||
com_nav_setting_data: 'تحكم في البيانات',
|
com_nav_setting_data: 'تحكم في البيانات',
|
||||||
/* The following are AI translated */
|
/* The following are AI translated */
|
||||||
|
com_ui_date_today: 'اليوم',
|
||||||
|
com_ui_date_yesterday: 'أمس',
|
||||||
|
com_ui_date_previous_7_days: 'الأيام السبعة السابقة',
|
||||||
|
com_ui_date_previous_30_days: 'الـ 30 يومًا السابقة',
|
||||||
|
com_ui_date_january: 'يناير',
|
||||||
|
com_ui_date_february: 'فبراير',
|
||||||
|
com_ui_date_march: 'مارس',
|
||||||
|
com_ui_date_april: 'أبريل',
|
||||||
|
com_ui_date_may: 'مايو',
|
||||||
|
com_ui_date_june: 'يونيو',
|
||||||
|
com_ui_date_july: 'يوليو',
|
||||||
|
com_ui_date_august: 'أغسطس',
|
||||||
|
com_ui_date_september: 'سبتمبر',
|
||||||
|
com_ui_date_october: 'أكتوبر',
|
||||||
|
com_ui_date_november: 'نوفمبر',
|
||||||
|
com_ui_date_december: 'ديسمبر',
|
||||||
|
com_ui_nothing_found: 'لم يتم العثور على أي شيء',
|
||||||
|
com_ui_go_to_conversation: 'انتقل إلى المحادثة',
|
||||||
com_error_moderation:
|
com_error_moderation:
|
||||||
'يبدو أن المحتوى المقدم قد تم وضع علامة عليه من قبل نظام الرقابة لدينا لعدم توافقه مع إرشادات مجتمعنا. لا نستطيع المضي قدمًا في هذا الموضوع المحدد. إذا كانت لديك أسئلة أخرى أو مواضيع ترغب في استكشافها، يرجى تحرير رسالتك، أو إنشاء محادثة جديدة.',
|
'يبدو أن المحتوى المقدم قد تم وضع علامة عليه من قبل نظام الرقابة لدينا لعدم توافقه مع إرشادات مجتمعنا. لا نستطيع المضي قدمًا في هذا الموضوع المحدد. إذا كانت لديك أسئلة أخرى أو مواضيع ترغب في استكشافها، يرجى تحرير رسالتك، أو إنشاء محادثة جديدة.',
|
||||||
com_error_no_user_key: 'لم يتم العثور على مفتاح. يرجى تقديم مفتاح والمحاولة مرة أخرى.',
|
com_error_no_user_key: 'لم يتم العثور على مفتاح. يرجى تقديم مفتاح والمحاولة مرة أخرى.',
|
||||||
|
@ -1534,6 +1552,78 @@ export const comparisons = {
|
||||||
english: 'Data controls',
|
english: 'Data controls',
|
||||||
translated: 'تحكم في البيانات',
|
translated: 'تحكم في البيانات',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: 'اليوم',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: 'أمس',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: 'الأيام السبعة السابقة',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: 'الـ 30 يومًا السابقة',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: 'يناير',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: 'فبراير',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: 'مارس',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: 'أبريل',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: 'مايو',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: 'يونيو',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: 'يوليو',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: 'أغسطس',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: 'سبتمبر',
|
||||||
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: 'أكتوبر',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: 'نوفمبر',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: 'ديسمبر',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: 'لم يتم العثور على أي شيء',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: 'انتقل إلى المحادثة',
|
||||||
|
},
|
||||||
com_error_moderation: {
|
com_error_moderation: {
|
||||||
english:
|
english:
|
||||||
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
||||||
|
|
|
@ -464,6 +464,24 @@ export default {
|
||||||
com_nav_setting_account: 'Konto',
|
com_nav_setting_account: 'Konto',
|
||||||
com_nav_language: 'Sprache',
|
com_nav_language: 'Sprache',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_date_today: 'Heute',
|
||||||
|
com_ui_date_yesterday: 'Gestern',
|
||||||
|
com_ui_date_previous_7_days: 'Letzte 7 Tage',
|
||||||
|
com_ui_date_previous_30_days: 'Letzte 30 Tage',
|
||||||
|
com_ui_date_january: 'Januar',
|
||||||
|
com_ui_date_february: 'Februar',
|
||||||
|
com_ui_date_march: 'März',
|
||||||
|
com_ui_date_april: 'April',
|
||||||
|
com_ui_date_may: 'Mai',
|
||||||
|
com_ui_date_june: 'Juni',
|
||||||
|
com_ui_date_july: 'Juli',
|
||||||
|
com_ui_date_august: 'August',
|
||||||
|
com_ui_date_september: 'September',
|
||||||
|
com_ui_date_october: 'Oktober',
|
||||||
|
com_ui_date_november: 'November',
|
||||||
|
com_ui_date_december: 'Dezember',
|
||||||
|
com_ui_nothing_found: 'Keine Ergebnisse gefunden',
|
||||||
|
com_ui_go_to_conversation: 'Zum Chat wechseln',
|
||||||
com_error_moderation:
|
com_error_moderation:
|
||||||
'Es sieht so aus, als ob der übermittelte Inhalt von unserem Moderationssystem als nicht konform mit unseren Gemeinschaftsrichtlinien markiert wurde. Wir können mit diesem spezifischen Thema leider nicht fortfahren. Wenn du andere Fragen oder Themen hast, die du gerne erörtern möchtest, bearbeite bitte deine Nachricht oder starte eine neue Konversation.',
|
'Es sieht so aus, als ob der übermittelte Inhalt von unserem Moderationssystem als nicht konform mit unseren Gemeinschaftsrichtlinien markiert wurde. Wir können mit diesem spezifischen Thema leider nicht fortfahren. Wenn du andere Fragen oder Themen hast, die du gerne erörtern möchtest, bearbeite bitte deine Nachricht oder starte eine neue Konversation.',
|
||||||
com_error_no_user_key:
|
com_error_no_user_key:
|
||||||
|
@ -2203,6 +2221,78 @@ export const comparisons = {
|
||||||
english: 'Language',
|
english: 'Language',
|
||||||
translated: 'Sprache',
|
translated: 'Sprache',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: 'Heute',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: 'Gestern',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: 'Letzte 7 Tage',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: 'Letzte 30 Tage',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: 'Januar',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: 'Februar',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: 'März',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: 'April',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: 'Mai',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: 'Juni',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: 'Juli',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: 'August',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: 'September',
|
||||||
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: 'Oktober',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: 'November',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: 'Dezember',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: 'Keine Ergebnisse gefunden',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: 'Zum Chat wechseln',
|
||||||
|
},
|
||||||
com_error_moderation: {
|
com_error_moderation: {
|
||||||
english:
|
english:
|
||||||
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
||||||
|
|
|
@ -54,6 +54,22 @@ export default {
|
||||||
com_assistants_update_error: 'There was an error updating your assistant.',
|
com_assistants_update_error: 'There was an error updating your assistant.',
|
||||||
com_assistants_create_success: 'Successfully created',
|
com_assistants_create_success: 'Successfully created',
|
||||||
com_assistants_create_error: 'There was an error creating your assistant.',
|
com_assistants_create_error: 'There was an error creating your assistant.',
|
||||||
|
com_ui_date_today: 'Today',
|
||||||
|
com_ui_date_yesterday: 'Yesterday',
|
||||||
|
com_ui_date_previous_7_days: 'Previous 7 days',
|
||||||
|
com_ui_date_previous_30_days: 'Previous 30 days',
|
||||||
|
com_ui_date_january: 'January',
|
||||||
|
com_ui_date_february: 'February',
|
||||||
|
com_ui_date_march: 'March',
|
||||||
|
com_ui_date_april: 'April',
|
||||||
|
com_ui_date_may: 'May',
|
||||||
|
com_ui_date_june: 'June',
|
||||||
|
com_ui_date_july: 'July',
|
||||||
|
com_ui_date_august: 'August',
|
||||||
|
com_ui_date_september: 'September',
|
||||||
|
com_ui_date_october: 'October',
|
||||||
|
com_ui_date_november: 'November',
|
||||||
|
com_ui_date_december: 'December',
|
||||||
com_ui_field_required: 'This field is required',
|
com_ui_field_required: 'This field is required',
|
||||||
com_ui_download_error: 'Error downloading file. The file may have been deleted.',
|
com_ui_download_error: 'Error downloading file. The file may have been deleted.',
|
||||||
com_ui_attach_error_type: 'Unsupported file type for endpoint:',
|
com_ui_attach_error_type: 'Unsupported file type for endpoint:',
|
||||||
|
@ -165,6 +181,8 @@ export default {
|
||||||
com_ui_revoke: 'Revoke',
|
com_ui_revoke: 'Revoke',
|
||||||
com_ui_revoke_info: 'Revoke all user provided credentials',
|
com_ui_revoke_info: 'Revoke all user provided credentials',
|
||||||
com_ui_import_conversation: 'Import',
|
com_ui_import_conversation: 'Import',
|
||||||
|
com_ui_nothing_found: 'Nothing found',
|
||||||
|
com_ui_go_to_conversation: 'Go to conversation',
|
||||||
com_ui_import_conversation_info: 'Import conversations from a JSON file',
|
com_ui_import_conversation_info: 'Import conversations from a JSON file',
|
||||||
com_ui_import_conversation_success: 'Conversations imported successfully',
|
com_ui_import_conversation_success: 'Conversations imported successfully',
|
||||||
com_ui_import_conversation_error: 'There was an error importing your conversations',
|
com_ui_import_conversation_error: 'There was an error importing your conversations',
|
||||||
|
|
|
@ -458,6 +458,24 @@ export default {
|
||||||
com_nav_lang_auto: 'Detección automática',
|
com_nav_lang_auto: 'Detección automática',
|
||||||
com_nav_lang_spanish: 'Español',
|
com_nav_lang_spanish: 'Español',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_date_today: 'Hoy',
|
||||||
|
com_ui_date_yesterday: 'Ayer',
|
||||||
|
com_ui_date_previous_7_days: 'Últimos 7 días',
|
||||||
|
com_ui_date_previous_30_days: 'Últimos 30 días',
|
||||||
|
com_ui_date_january: 'Enero',
|
||||||
|
com_ui_date_february: 'Febrero',
|
||||||
|
com_ui_date_march: 'Marzo',
|
||||||
|
com_ui_date_april: 'Abril',
|
||||||
|
com_ui_date_may: 'Mayo',
|
||||||
|
com_ui_date_june: 'Junio',
|
||||||
|
com_ui_date_july: 'Julio',
|
||||||
|
com_ui_date_august: 'Agosto',
|
||||||
|
com_ui_date_september: 'Septiembre',
|
||||||
|
com_ui_date_october: 'Octubre',
|
||||||
|
com_ui_date_november: 'Noviembre',
|
||||||
|
com_ui_date_december: 'Diciembre',
|
||||||
|
com_ui_nothing_found: 'No se encontró nada',
|
||||||
|
com_ui_go_to_conversation: 'Ir a la conversación',
|
||||||
com_error_moderation:
|
com_error_moderation:
|
||||||
'Parece que el contenido enviado ha sido marcado por nuestro sistema de moderación por no estar alineado con nuestras pautas comunitarias. No podemos proceder con este tema específico. Si tiene alguna otra pregunta o tema que le gustaría explorar, por favor edite su mensaje o cree una nueva conversación.',
|
'Parece que el contenido enviado ha sido marcado por nuestro sistema de moderación por no estar alineado con nuestras pautas comunitarias. No podemos proceder con este tema específico. Si tiene alguna otra pregunta o tema que le gustaría explorar, por favor edite su mensaje o cree una nueva conversación.',
|
||||||
com_error_no_user_key:
|
com_error_no_user_key:
|
||||||
|
@ -2184,6 +2202,78 @@ export const comparisons = {
|
||||||
english: 'Español',
|
english: 'Español',
|
||||||
translated: 'Español',
|
translated: 'Español',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: 'Hoy',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: 'Ayer',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: 'Últimos 7 días',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: 'Últimos 30 días',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: 'Enero',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: 'Febrero',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: 'Marzo',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: 'Abril',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: 'Mayo',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: 'Junio',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: 'Julio',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: 'Agosto',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: 'Septiembre',
|
||||||
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: 'Octubre',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: 'Noviembre',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: 'Diciembre',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: 'No se encontró nada',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: 'Ir a la conversación',
|
||||||
|
},
|
||||||
com_error_moderation: {
|
com_error_moderation: {
|
||||||
english:
|
english:
|
||||||
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
||||||
|
|
|
@ -347,6 +347,55 @@ export default {
|
||||||
com_nav_setting_data: 'Contrôles des données',
|
com_nav_setting_data: 'Contrôles des données',
|
||||||
com_nav_setting_account: 'Compte',
|
com_nav_setting_account: 'Compte',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_date_today: 'Aujourd\'hui',
|
||||||
|
com_ui_date_yesterday: 'Hier',
|
||||||
|
com_ui_date_previous_7_days: '7 derniers jours',
|
||||||
|
com_ui_date_previous_30_days: '30 derniers jours',
|
||||||
|
com_ui_date_january: 'Janvier',
|
||||||
|
com_ui_date_february: 'Février',
|
||||||
|
com_ui_date_march: 'Mars',
|
||||||
|
com_ui_date_april: 'Avril',
|
||||||
|
com_ui_date_may: 'Mai',
|
||||||
|
com_ui_date_june: 'Juin',
|
||||||
|
com_ui_date_july: 'Juillet',
|
||||||
|
com_ui_date_august: 'Août',
|
||||||
|
com_ui_date_september: 'Septembre',
|
||||||
|
com_ui_date_october: 'Octobre',
|
||||||
|
com_ui_date_november: 'Novembre',
|
||||||
|
com_ui_date_december: 'Décembre',
|
||||||
|
com_ui_nothing_found: 'Aucun résultat trouvé',
|
||||||
|
com_ui_go_to_conversation: 'Aller à la conversation',
|
||||||
|
com_nav_tool_add: 'Ajouter',
|
||||||
|
com_nav_tool_remove: 'Supprimer',
|
||||||
|
com_nav_tool_dialog: 'Outils de l\'assistant',
|
||||||
|
com_nav_tool_dialog_description:
|
||||||
|
'L\'assistant doit être sauvegardé pour conserver les sélections d\'outils.',
|
||||||
|
com_nav_tool_search: 'Outils de recherche',
|
||||||
|
com_nav_my_files: 'Mes fichiers',
|
||||||
|
com_nav_enter_to_send: 'Appuyez sur Entrée pour envoyer des messages',
|
||||||
|
com_nav_show_code: 'Toujours afficher le code lors de l\'utilisation de l\'interpréteur de code',
|
||||||
|
com_nav_archived_chats_empty: 'Vous n\'avez aucune conversation archivée.',
|
||||||
|
com_nav_language: 'Langue',
|
||||||
|
com_nav_lang_auto: 'Détection automatique',
|
||||||
|
com_nav_lang_english: 'Anglais',
|
||||||
|
com_nav_lang_chinese: 'Chinois',
|
||||||
|
com_nav_lang_german: 'Allemand',
|
||||||
|
com_nav_lang_spanish: 'Espagnol',
|
||||||
|
com_nav_lang_french: 'Français',
|
||||||
|
com_nav_lang_italian: 'Italien',
|
||||||
|
com_nav_lang_polish: 'Polonais',
|
||||||
|
com_nav_lang_brazilian_portuguese: 'Portugais brésilien',
|
||||||
|
com_nav_lang_russian: 'Russe',
|
||||||
|
com_nav_lang_japanese: 'Japonais',
|
||||||
|
com_nav_lang_swedish: 'Suédois',
|
||||||
|
com_nav_lang_korean: 'Coréen',
|
||||||
|
com_nav_lang_vietnamese: 'Vietnamien',
|
||||||
|
com_nav_lang_traditionalchinese: 'Chinois traditionnel',
|
||||||
|
com_nav_lang_arabic: 'Arabe',
|
||||||
|
com_nav_lang_turkish: 'Turc',
|
||||||
|
com_nav_lang_dutch: 'Néerlandais',
|
||||||
|
com_nav_lang_indonesia: 'Indonésie',
|
||||||
|
com_nav_lang_hebrew: 'Hébreu',
|
||||||
com_error_moderation:
|
com_error_moderation:
|
||||||
'Il semble que le contenu soumis ait été signalé par notre système de modération pour ne pas être conforme à nos lignes directrices communautaires. Nous ne pouvons pas procéder avec ce sujet spécifique. Si vous avez d\'autres questions ou sujets que vous souhaitez explorer, veuillez modifier votre message ou créer une nouvelle conversation.',
|
'Il semble que le contenu soumis ait été signalé par notre système de modération pour ne pas être conforme à nos lignes directrices communautaires. Nous ne pouvons pas procéder avec ce sujet spécifique. Si vous avez d\'autres questions ou sujets que vous souhaitez explorer, veuillez modifier votre message ou créer une nouvelle conversation.',
|
||||||
com_error_no_user_key: 'Aucune clé trouvée. Veuillez fournir une clé et réessayer.',
|
com_error_no_user_key: 'Aucune clé trouvée. Veuillez fournir une clé et réessayer.',
|
||||||
|
@ -1730,6 +1779,198 @@ export const comparisons = {
|
||||||
english: 'Account',
|
english: 'Account',
|
||||||
translated: 'Compte',
|
translated: 'Compte',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: 'Aujourd\'hui',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: 'Hier',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: '7 derniers jours',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: '30 derniers jours',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: 'Janvier',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: 'Février',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: 'Mars',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: 'Avril',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: 'Mai',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: 'Juin',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: 'Juillet',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: 'Août',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: 'Septembre',
|
||||||
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: 'Octobre',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: 'Novembre',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: 'Décembre',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: 'Aucun résultat trouvé',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: 'Aller à la conversation',
|
||||||
|
},
|
||||||
|
com_nav_tool_add: {
|
||||||
|
english: 'Add',
|
||||||
|
translated: 'Ajouter',
|
||||||
|
},
|
||||||
|
com_nav_tool_remove: {
|
||||||
|
english: 'Remove',
|
||||||
|
translated: 'Supprimer',
|
||||||
|
},
|
||||||
|
com_nav_tool_dialog: {
|
||||||
|
english: 'Assistant Tools',
|
||||||
|
translated: 'Outils de l\'assistant',
|
||||||
|
},
|
||||||
|
com_nav_tool_dialog_description: {
|
||||||
|
english: 'Assistant must be saved to persist tool selections.',
|
||||||
|
translated: 'L\'assistant doit être sauvegardé pour conserver les sélections d\'outils.',
|
||||||
|
},
|
||||||
|
com_nav_tool_search: {
|
||||||
|
english: 'Search tools',
|
||||||
|
translated: 'Outils de recherche',
|
||||||
|
},
|
||||||
|
com_nav_my_files: {
|
||||||
|
english: 'My Files',
|
||||||
|
translated: 'Mes fichiers',
|
||||||
|
},
|
||||||
|
com_nav_enter_to_send: {
|
||||||
|
english: 'Press Enter to send messages',
|
||||||
|
translated: 'Appuyez sur Entrée pour envoyer des messages',
|
||||||
|
},
|
||||||
|
com_nav_show_code: {
|
||||||
|
english: 'Always show code when using code interpreter',
|
||||||
|
translated: 'Toujours afficher le code lors de l\'utilisation de l\'interpréteur de code',
|
||||||
|
},
|
||||||
|
com_nav_archived_chats_empty: {
|
||||||
|
english: 'You have no archived conversations.',
|
||||||
|
translated: 'Vous n\'avez aucune conversation archivée.',
|
||||||
|
},
|
||||||
|
com_nav_language: {
|
||||||
|
english: 'Language',
|
||||||
|
translated: 'Langue',
|
||||||
|
},
|
||||||
|
com_nav_lang_auto: {
|
||||||
|
english: 'Auto detect',
|
||||||
|
translated: 'Détection automatique',
|
||||||
|
},
|
||||||
|
com_nav_lang_english: {
|
||||||
|
english: 'English',
|
||||||
|
translated: 'Anglais',
|
||||||
|
},
|
||||||
|
com_nav_lang_chinese: {
|
||||||
|
english: '中文',
|
||||||
|
translated: 'Chinois',
|
||||||
|
},
|
||||||
|
com_nav_lang_german: {
|
||||||
|
english: 'Deutsch',
|
||||||
|
translated: 'Allemand',
|
||||||
|
},
|
||||||
|
com_nav_lang_spanish: {
|
||||||
|
english: 'Español',
|
||||||
|
translated: 'Espagnol',
|
||||||
|
},
|
||||||
|
com_nav_lang_french: {
|
||||||
|
english: 'Français ',
|
||||||
|
translated: 'Français',
|
||||||
|
},
|
||||||
|
com_nav_lang_italian: {
|
||||||
|
english: 'Italiano',
|
||||||
|
translated: 'Italien',
|
||||||
|
},
|
||||||
|
com_nav_lang_polish: {
|
||||||
|
english: 'Polski',
|
||||||
|
translated: 'Polonais',
|
||||||
|
},
|
||||||
|
com_nav_lang_brazilian_portuguese: {
|
||||||
|
english: 'Português Brasileiro',
|
||||||
|
translated: 'Portugais brésilien',
|
||||||
|
},
|
||||||
|
com_nav_lang_russian: {
|
||||||
|
english: 'Русский',
|
||||||
|
translated: 'Russe',
|
||||||
|
},
|
||||||
|
com_nav_lang_japanese: {
|
||||||
|
english: '日本語',
|
||||||
|
translated: 'Japonais',
|
||||||
|
},
|
||||||
|
com_nav_lang_swedish: {
|
||||||
|
english: 'Svenska',
|
||||||
|
translated: 'Suédois',
|
||||||
|
},
|
||||||
|
com_nav_lang_korean: {
|
||||||
|
english: '한국어',
|
||||||
|
translated: 'Coréen',
|
||||||
|
},
|
||||||
|
com_nav_lang_vietnamese: {
|
||||||
|
english: 'Tiếng Việt',
|
||||||
|
translated: 'Vietnamien',
|
||||||
|
},
|
||||||
|
com_nav_lang_traditionalchinese: {
|
||||||
|
english: '繁體中文',
|
||||||
|
translated: 'Chinois traditionnel',
|
||||||
|
},
|
||||||
|
com_nav_lang_arabic: {
|
||||||
|
english: 'العربية',
|
||||||
|
translated: 'Arabe',
|
||||||
|
},
|
||||||
|
com_nav_lang_turkish: {
|
||||||
|
english: 'Türkçe',
|
||||||
|
translated: 'Turc',
|
||||||
|
},
|
||||||
|
com_nav_lang_dutch: {
|
||||||
|
english: 'Nederlands',
|
||||||
|
translated: 'Néerlandais',
|
||||||
|
},
|
||||||
|
com_nav_lang_indonesia: {
|
||||||
|
english: 'Indonesia',
|
||||||
|
translated: 'Indonésie',
|
||||||
|
},
|
||||||
|
com_nav_lang_hebrew: {
|
||||||
|
english: 'עברית',
|
||||||
|
translated: 'Hébreu',
|
||||||
|
},
|
||||||
com_error_moderation: {
|
com_error_moderation: {
|
||||||
english:
|
english:
|
||||||
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
||||||
|
|
|
@ -508,6 +508,24 @@ export default {
|
||||||
com_nav_setting_data: 'Controlli dati',
|
com_nav_setting_data: 'Controlli dati',
|
||||||
com_nav_setting_account: 'Account',
|
com_nav_setting_account: 'Account',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_date_today: 'Oggi',
|
||||||
|
com_ui_date_yesterday: 'Ieri',
|
||||||
|
com_ui_date_previous_7_days: 'Ultimi 7 giorni',
|
||||||
|
com_ui_date_previous_30_days: 'Ultimi 30 giorni',
|
||||||
|
com_ui_date_january: 'Gennaio',
|
||||||
|
com_ui_date_february: 'Febbraio',
|
||||||
|
com_ui_date_march: 'Marzo',
|
||||||
|
com_ui_date_april: 'Aprile',
|
||||||
|
com_ui_date_may: 'Maggio',
|
||||||
|
com_ui_date_june: 'Giugno',
|
||||||
|
com_ui_date_july: 'Luglio',
|
||||||
|
com_ui_date_august: 'Agosto',
|
||||||
|
com_ui_date_september: 'Settembre',
|
||||||
|
com_ui_date_october: 'Ottobre',
|
||||||
|
com_ui_date_november: 'Novembre',
|
||||||
|
com_ui_date_december: 'Dicembre',
|
||||||
|
com_ui_nothing_found: 'Non è stato trovato nulla',
|
||||||
|
com_ui_go_to_conversation: 'Vai alla conversazione',
|
||||||
com_user_message: 'Mostra nome utente nei messaggi',
|
com_user_message: 'Mostra nome utente nei messaggi',
|
||||||
com_ui_fork: 'Duplica',
|
com_ui_fork: 'Duplica',
|
||||||
com_ui_mention: 'Menziona un endpoint, assistente o preset per passare rapidamente ad esso',
|
com_ui_mention: 'Menziona un endpoint, assistente o preset per passare rapidamente ad esso',
|
||||||
|
@ -2341,6 +2359,78 @@ export const comparisons = {
|
||||||
english: 'Account',
|
english: 'Account',
|
||||||
translated: 'Account',
|
translated: 'Account',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: 'Oggi',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: 'Ieri',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: 'Ultimi 7 giorni',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: 'Ultimi 30 giorni',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: 'Gennaio',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: 'Febbraio',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: 'Marzo',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: 'Aprile',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: 'Maggio',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: 'Giugno',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: 'Luglio',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: 'Agosto',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: 'Settembre',
|
||||||
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: 'Ottobre',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: 'Novembre',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: 'Dicembre',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: 'Non è stato trovato nulla',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: 'Vai alla conversazione',
|
||||||
|
},
|
||||||
com_user_message: {
|
com_user_message: {
|
||||||
english: 'You',
|
english: 'You',
|
||||||
translated: 'Mostra nome utente nei messaggi',
|
translated: 'Mostra nome utente nei messaggi',
|
||||||
|
|
|
@ -455,6 +455,24 @@ export default {
|
||||||
com_nav_setting_data: 'データ管理',
|
com_nav_setting_data: 'データ管理',
|
||||||
com_nav_setting_account: 'アカウント',
|
com_nav_setting_account: 'アカウント',
|
||||||
/* The following are AI translated */
|
/* The following are AI translated */
|
||||||
|
com_ui_date_today: '今日',
|
||||||
|
com_ui_date_yesterday: '昨日',
|
||||||
|
com_ui_date_previous_7_days: '過去7日間',
|
||||||
|
com_ui_date_previous_30_days: '過去30日間',
|
||||||
|
com_ui_date_january: '1月',
|
||||||
|
com_ui_date_february: '2月',
|
||||||
|
com_ui_date_march: '3月',
|
||||||
|
com_ui_date_april: '4月',
|
||||||
|
com_ui_date_may: '5月',
|
||||||
|
com_ui_date_june: '6月',
|
||||||
|
com_ui_date_july: '7月',
|
||||||
|
com_ui_date_august: '8月',
|
||||||
|
com_ui_date_september: '9月',
|
||||||
|
com_ui_date_october: '10月',
|
||||||
|
com_ui_date_november: '11月',
|
||||||
|
com_ui_date_december: '12月',
|
||||||
|
com_ui_nothing_found: '該当するものが見つかりませんでした',
|
||||||
|
com_ui_go_to_conversation: '会話に移動する',
|
||||||
com_error_invalid_user_key: '無効なキーが提供されました。キーを入力して再試行してください。',
|
com_error_invalid_user_key: '無効なキーが提供されました。キーを入力して再試行してください。',
|
||||||
com_ui_none_selected: '選択されていません',
|
com_ui_none_selected: '選択されていません',
|
||||||
com_ui_fork: '分岐',
|
com_ui_fork: '分岐',
|
||||||
|
@ -2193,6 +2211,78 @@ export const comparisons = {
|
||||||
english: 'Account',
|
english: 'Account',
|
||||||
translated: 'アカウント',
|
translated: 'アカウント',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: '今日',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: '昨日',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: '過去7日間',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: '過去30日間',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: '1月',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: '2月',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: '3月',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: '4月',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: '5月',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: '6月',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: '7月',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: '8月',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: '9月',
|
||||||
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: '10月',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: '11月',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: '12月',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: '該当するものが見つかりませんでした',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: '会話に移動する',
|
||||||
|
},
|
||||||
com_error_invalid_user_key: {
|
com_error_invalid_user_key: {
|
||||||
english: 'Invalid key provided. Please provide a key and try again.',
|
english: 'Invalid key provided. Please provide a key and try again.',
|
||||||
translated: '無効なキーが提供されました。キーを入力して再試行してください。',
|
translated: '無効なキーが提供されました。キーを入力して再試行してください。',
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -364,6 +364,24 @@ export default {
|
||||||
com_ui_upload_error: 'Произошла ошибка при загрузке вашего файла',
|
com_ui_upload_error: 'Произошла ошибка при загрузке вашего файла',
|
||||||
com_user_message: 'Вы',
|
com_user_message: 'Вы',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_date_today: 'Сегодня',
|
||||||
|
com_ui_date_yesterday: 'Вчера',
|
||||||
|
com_ui_date_previous_7_days: 'Предыдущие 7 дней',
|
||||||
|
com_ui_date_previous_30_days: 'За последние 30 дней',
|
||||||
|
com_ui_date_january: 'Январь',
|
||||||
|
com_ui_date_february: 'Февраль',
|
||||||
|
com_ui_date_march: 'Март',
|
||||||
|
com_ui_date_april: 'Апрель',
|
||||||
|
com_ui_date_may: 'Май',
|
||||||
|
com_ui_date_june: 'Июнь',
|
||||||
|
com_ui_date_july: 'Июль',
|
||||||
|
com_ui_date_august: 'Август',
|
||||||
|
com_ui_date_september: 'Сентябрь',
|
||||||
|
com_ui_date_october: 'Октябрь',
|
||||||
|
com_ui_date_november: 'Ноябрь',
|
||||||
|
com_ui_date_december: 'Декабрь',
|
||||||
|
com_ui_nothing_found: 'Ничего не найдено',
|
||||||
|
com_ui_go_to_conversation: 'Перейти к беседе',
|
||||||
com_error_moderation:
|
com_error_moderation:
|
||||||
'К сожалению, отправленный вами контент был помечен нашей системой модерации как не соответствующий правилам сообщества. Мы не можем продолжить обсуждение этой конкретной темы. Если у вас есть другие вопросы или темы, которые вы хотели бы обсудить, пожалуйста, отредактируйте сообщение или начните новый диалог.',
|
'К сожалению, отправленный вами контент был помечен нашей системой модерации как не соответствующий правилам сообщества. Мы не можем продолжить обсуждение этой конкретной темы. Если у вас есть другие вопросы или темы, которые вы хотели бы обсудить, пожалуйста, отредактируйте сообщение или начните новый диалог.',
|
||||||
com_error_no_user_key: 'Ключ не найден. Пожалуйста, укажите ключ и повторите попытку.',
|
com_error_no_user_key: 'Ключ не найден. Пожалуйста, укажите ключ и повторите попытку.',
|
||||||
|
@ -1846,6 +1864,78 @@ export const comparisons = {
|
||||||
english: 'You',
|
english: 'You',
|
||||||
translated: 'Вы',
|
translated: 'Вы',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: 'Сегодня',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: 'Вчера',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: 'Предыдущие 7 дней',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: 'За последние 30 дней',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: 'Январь',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: 'Февраль',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: 'Март',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: 'Апрель',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: 'Май',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: 'Июнь',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: 'Июль',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: 'Август',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: 'Сентябрь',
|
||||||
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: 'Октябрь',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: 'Ноябрь',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: 'Декабрь',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: 'Ничего не найдено',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: 'Перейти к беседе',
|
||||||
|
},
|
||||||
com_error_moderation: {
|
com_error_moderation: {
|
||||||
english:
|
english:
|
||||||
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
||||||
|
|
|
@ -417,6 +417,21 @@ export default {
|
||||||
com_nav_setting_data: '数据管理',
|
com_nav_setting_data: '数据管理',
|
||||||
com_nav_setting_account: '账户',
|
com_nav_setting_account: '账户',
|
||||||
/* The following are AI Translated */
|
/* The following are AI Translated */
|
||||||
|
com_ui_date_today: '今天',
|
||||||
|
com_ui_date_yesterday: '昨天',
|
||||||
|
com_ui_date_previous_7_days: '过去7天',
|
||||||
|
com_ui_date_previous_30_days: '过去30天',
|
||||||
|
com_ui_date_january: '一月',
|
||||||
|
com_ui_date_february: '二月',
|
||||||
|
com_ui_date_march: '三月',
|
||||||
|
com_ui_date_april: '四月',
|
||||||
|
com_ui_date_may: '五月',
|
||||||
|
com_ui_date_june: '六月',
|
||||||
|
com_ui_date_july: '七月',
|
||||||
|
com_ui_date_august: '八月',
|
||||||
|
com_ui_date_september: '九月',
|
||||||
|
com_ui_nothing_found: '未找到任何内容',
|
||||||
|
com_ui_go_to_conversation: '转到对话',
|
||||||
com_error_moderation:
|
com_error_moderation:
|
||||||
'很抱歉,您提交的内容被我们的审核系统标记为不符合社区指引。我们无法就此特定主题继续交流。如果您有任何其他问题或想探讨的话题,请编辑您的消息或开启新的对话。',
|
'很抱歉,您提交的内容被我们的审核系统标记为不符合社区指引。我们无法就此特定主题继续交流。如果您有任何其他问题或想探讨的话题,请编辑您的消息或开启新的对话。',
|
||||||
com_error_no_user_key: '没有找到密钥。请提供密钥后重试。',
|
com_error_no_user_key: '没有找到密钥。请提供密钥后重试。',
|
||||||
|
@ -2096,6 +2111,66 @@ export const comparisons = {
|
||||||
english: 'Account',
|
english: 'Account',
|
||||||
translated: '账户',
|
translated: '账户',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: '今天',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: '昨天',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: '过去7天',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: '过去30天',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: '一月',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: '二月',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: '三月',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: '四月',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: '五月',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: '六月',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: '七月',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: '八月',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: '九月',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: '未找到任何内容',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: '转到对话',
|
||||||
|
},
|
||||||
com_error_moderation: {
|
com_error_moderation: {
|
||||||
english:
|
english:
|
||||||
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
||||||
|
|
|
@ -266,6 +266,24 @@ export default {
|
||||||
com_nav_setting_general: '一般',
|
com_nav_setting_general: '一般',
|
||||||
com_nav_setting_data: '資料控制',
|
com_nav_setting_data: '資料控制',
|
||||||
/* The following are AI translated */
|
/* The following are AI translated */
|
||||||
|
com_ui_date_today: '今天',
|
||||||
|
com_ui_date_yesterday: '昨天',
|
||||||
|
com_ui_date_previous_7_days: '前 7 天',
|
||||||
|
com_ui_date_previous_30_days: '過去 30 天',
|
||||||
|
com_ui_date_january: '一月',
|
||||||
|
com_ui_date_february: '二月',
|
||||||
|
com_ui_date_march: '三月',
|
||||||
|
com_ui_date_april: '四月',
|
||||||
|
com_ui_date_may: '五月',
|
||||||
|
com_ui_date_june: '六月',
|
||||||
|
com_ui_date_july: '七月',
|
||||||
|
com_ui_date_august: '八月',
|
||||||
|
com_ui_date_september: '九月',
|
||||||
|
com_ui_date_october: '十月',
|
||||||
|
com_ui_date_november: '十一月',
|
||||||
|
com_ui_date_december: '十二月',
|
||||||
|
com_ui_nothing_found: '找不到任何內容',
|
||||||
|
com_ui_go_to_conversation: '前往對話',
|
||||||
com_error_moderation:
|
com_error_moderation:
|
||||||
'似乎您所提交的內容被我們的內容審查系統標記為不符合社群準則。我們無法就此特定主題繼續進行。如果您有任何其他問題或想要探討的主題,請編輯您的訊息或開啟新的對話。',
|
'似乎您所提交的內容被我們的內容審查系統標記為不符合社群準則。我們無法就此特定主題繼續進行。如果您有任何其他問題或想要探討的主題,請編輯您的訊息或開啟新的對話。',
|
||||||
com_error_no_user_key: '找不到金鑰,請提供金鑰後再試一次。',
|
com_error_no_user_key: '找不到金鑰,請提供金鑰後再試一次。',
|
||||||
|
@ -1509,6 +1527,78 @@ export const comparisons = {
|
||||||
english: 'Data controls',
|
english: 'Data controls',
|
||||||
translated: '資料控制',
|
translated: '資料控制',
|
||||||
},
|
},
|
||||||
|
com_ui_date_today: {
|
||||||
|
english: 'Today',
|
||||||
|
translated: '今天',
|
||||||
|
},
|
||||||
|
com_ui_date_yesterday: {
|
||||||
|
english: 'Yesterday',
|
||||||
|
translated: '昨天',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_7_days: {
|
||||||
|
english: 'Previous 7 days',
|
||||||
|
translated: '前 7 天',
|
||||||
|
},
|
||||||
|
com_ui_date_previous_30_days: {
|
||||||
|
english: 'Previous 30 days',
|
||||||
|
translated: '過去 30 天',
|
||||||
|
},
|
||||||
|
com_ui_date_january: {
|
||||||
|
english: 'January',
|
||||||
|
translated: '一月',
|
||||||
|
},
|
||||||
|
com_ui_date_february: {
|
||||||
|
english: 'February',
|
||||||
|
translated: '二月',
|
||||||
|
},
|
||||||
|
com_ui_date_march: {
|
||||||
|
english: 'March',
|
||||||
|
translated: '三月',
|
||||||
|
},
|
||||||
|
com_ui_date_april: {
|
||||||
|
english: 'April',
|
||||||
|
translated: '四月',
|
||||||
|
},
|
||||||
|
com_ui_date_may: {
|
||||||
|
english: 'May',
|
||||||
|
translated: '五月',
|
||||||
|
},
|
||||||
|
com_ui_date_june: {
|
||||||
|
english: 'June',
|
||||||
|
translated: '六月',
|
||||||
|
},
|
||||||
|
com_ui_date_july: {
|
||||||
|
english: 'July',
|
||||||
|
translated: '七月',
|
||||||
|
},
|
||||||
|
com_ui_date_august: {
|
||||||
|
english: 'August',
|
||||||
|
translated: '八月',
|
||||||
|
},
|
||||||
|
com_ui_date_september: {
|
||||||
|
english: 'September',
|
||||||
|
translated: '九月',
|
||||||
|
},
|
||||||
|
com_ui_date_october: {
|
||||||
|
english: 'October',
|
||||||
|
translated: '十月',
|
||||||
|
},
|
||||||
|
com_ui_date_november: {
|
||||||
|
english: 'November',
|
||||||
|
translated: '十一月',
|
||||||
|
},
|
||||||
|
com_ui_date_december: {
|
||||||
|
english: 'December',
|
||||||
|
translated: '十二月',
|
||||||
|
},
|
||||||
|
com_ui_nothing_found: {
|
||||||
|
english: 'Nothing found',
|
||||||
|
translated: '找不到任何內容',
|
||||||
|
},
|
||||||
|
com_ui_go_to_conversation: {
|
||||||
|
english: 'Go to conversation',
|
||||||
|
translated: '前往對話',
|
||||||
|
},
|
||||||
com_error_moderation: {
|
com_error_moderation: {
|
||||||
english:
|
english:
|
||||||
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Outlet } from 'react-router-dom';
|
import { Outlet } from 'react-router-dom';
|
||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
import { useGetSearchEnabledQuery } from 'librechat-data-provider/react-query';
|
|
||||||
import type { ContextType } from '~/common';
|
import type { ContextType } from '~/common';
|
||||||
import { useAuthContext, useAssistantsMap, useFileMap } from '~/hooks';
|
import { useAuthContext, useAssistantsMap, useFileMap, useSearch } from '~/hooks';
|
||||||
import { AssistantsMapContext, FileMapContext } from '~/Providers';
|
import { AssistantsMapContext, FileMapContext, SearchContext } from '~/Providers';
|
||||||
import { Nav, MobileNav } from '~/components/Nav';
|
import { Nav, MobileNav } from '~/components/Nav';
|
||||||
import store from '~/store';
|
|
||||||
|
|
||||||
export default function Root() {
|
export default function Root() {
|
||||||
const { isAuthenticated } = useAuthContext();
|
const { isAuthenticated } = useAuthContext();
|
||||||
|
@ -15,42 +13,29 @@ export default function Root() {
|
||||||
return savedNavVisible !== null ? JSON.parse(savedNavVisible) : true;
|
return savedNavVisible !== null ? JSON.parse(savedNavVisible) : true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const setIsSearchEnabled = useSetRecoilState(store.isSearchEnabled);
|
const search = useSearch({ isAuthenticated });
|
||||||
|
|
||||||
const fileMap = useFileMap({ isAuthenticated });
|
const fileMap = useFileMap({ isAuthenticated });
|
||||||
const assistantsMap = useAssistantsMap({ isAuthenticated });
|
const assistantsMap = useAssistantsMap({ isAuthenticated });
|
||||||
const searchEnabledQuery = useGetSearchEnabledQuery({ enabled: isAuthenticated });
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (searchEnabledQuery.data) {
|
|
||||||
setIsSearchEnabled(searchEnabledQuery.data);
|
|
||||||
} else if (searchEnabledQuery.isError) {
|
|
||||||
console.error('Failed to get search enabled', searchEnabledQuery.error);
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
searchEnabledQuery.data,
|
|
||||||
searchEnabledQuery.error,
|
|
||||||
searchEnabledQuery.isError,
|
|
||||||
setIsSearchEnabled,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FileMapContext.Provider value={fileMap}>
|
<SearchContext.Provider value={search}>
|
||||||
<AssistantsMapContext.Provider value={assistantsMap}>
|
<FileMapContext.Provider value={fileMap}>
|
||||||
<div className="flex h-dvh">
|
<AssistantsMapContext.Provider value={assistantsMap}>
|
||||||
<div className="relative z-0 flex h-full w-full overflow-hidden">
|
<div className="flex h-dvh">
|
||||||
<Nav navVisible={navVisible} setNavVisible={setNavVisible} />
|
<div className="relative z-0 flex h-full w-full overflow-hidden">
|
||||||
<div className="relative flex h-full max-w-full flex-1 flex-col overflow-hidden">
|
<Nav navVisible={navVisible} setNavVisible={setNavVisible} />
|
||||||
<MobileNav setNavVisible={setNavVisible} />
|
<div className="relative flex h-full max-w-full flex-1 flex-col overflow-hidden">
|
||||||
<Outlet context={{ navVisible, setNavVisible } satisfies ContextType} />
|
<MobileNav setNavVisible={setNavVisible} />
|
||||||
|
<Outlet context={{ navVisible, setNavVisible } satisfies ContextType} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</AssistantsMapContext.Provider>
|
||||||
</AssistantsMapContext.Provider>
|
</FileMapContext.Provider>
|
||||||
</FileMapContext.Provider>
|
</SearchContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +1,42 @@
|
||||||
import React, { useEffect } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import MinimalMessagesWrapper from '~/components/Chat/Messages/MinimalMessages';
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import SearchMessage from '~/components/Chat/Messages/SearchMessage';
|
||||||
// import TextChat from '~/components/Input/TextChat';
|
import { useSearchContext, useFileMapContext } from '~/Providers';
|
||||||
|
import { useNavScrolling, useLocalize } from '~/hooks';
|
||||||
import { useConversation } from '~/hooks';
|
import { buildTree } from '~/utils';
|
||||||
import store from '~/store';
|
|
||||||
|
|
||||||
export default function Search() {
|
export default function Search() {
|
||||||
const [searchQuery, setSearchQuery] = useRecoilState(store.searchQuery);
|
const localize = useLocalize();
|
||||||
const conversation = useRecoilValue(store.conversation);
|
const fileMap = useFileMapContext();
|
||||||
const { searchPlaceholderConversation } = useConversation();
|
const { searchQuery, searchQueryRes } = useSearchContext();
|
||||||
const { query } = useParams();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
// when conversation changed or conversationId (in url) changed
|
const { containerRef } = useNavScrolling({
|
||||||
useEffect(() => {
|
setShowLoading: () => ({}),
|
||||||
if (conversation === null) {
|
hasNextPage: searchQueryRes?.hasNextPage,
|
||||||
// no current conversation, we need to do something
|
fetchNextPage: searchQueryRes?.fetchNextPage,
|
||||||
if (query) {
|
isFetchingNextPage: searchQueryRes?.isFetchingNextPage,
|
||||||
// create new
|
});
|
||||||
searchPlaceholderConversation();
|
|
||||||
setSearchQuery(query);
|
|
||||||
} else {
|
|
||||||
navigate('/c/new');
|
|
||||||
}
|
|
||||||
} else if (conversation?.conversationId === 'search') {
|
|
||||||
// jump to search page
|
|
||||||
if (searchQuery !== query) {
|
|
||||||
navigate(`/search/${searchQuery}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// conversationId (in url) should always follow conversation?.conversationId, unless conversation is null
|
|
||||||
navigate(`/chat/${conversation?.conversationId}`);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [conversation, query, searchQuery]);
|
|
||||||
|
|
||||||
// if not a search
|
const messages = useMemo(() => {
|
||||||
if (conversation?.conversationId !== 'search') {
|
const msgs = searchQueryRes?.data?.pages.flatMap((page) => page.messages) || [];
|
||||||
return null;
|
const dataTree = buildTree({ messages: msgs, fileMap });
|
||||||
}
|
return dataTree?.length === 0 ? null : dataTree ?? null;
|
||||||
// if query not match
|
}, [fileMap, searchQueryRes?.data?.pages]);
|
||||||
if (searchQuery !== query) {
|
|
||||||
return null;
|
if (!searchQuery || !searchQueryRes?.data) {
|
||||||
}
|
|
||||||
// if query is null
|
|
||||||
if (!query) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<MinimalMessagesWrapper ref={containerRef} className="pt-4">
|
||||||
{/* <Messages isSearchView={true} /> */}
|
{(messages && messages?.length == 0) || messages === null ? (
|
||||||
{/* <TextChat isSearchView={true} /> */}
|
<div className="my-auto flex h-full w-full items-center justify-center gap-1 bg-gray-50 p-3 text-lg text-gray-500 dark:border-gray-800/50 dark:bg-gray-800 dark:text-gray-300">
|
||||||
</>
|
{localize('com_ui_nothing_found')}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
messages?.map((message) => <SearchMessage key={message.messageId} message={message} />)
|
||||||
|
)}
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 h-[5%] bg-gradient-to-t from-gray-800 to-transparent" />
|
||||||
|
</MinimalMessagesWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import { createBrowserRouter, Navigate, Outlet } from 'react-router-dom';
|
import { createBrowserRouter, Navigate, Outlet } from 'react-router-dom';
|
||||||
import Root from './Root';
|
|
||||||
import ChatRoute from './ChatRoute';
|
|
||||||
// import Search from './Search';
|
|
||||||
import {
|
import {
|
||||||
Login,
|
Login,
|
||||||
Registration,
|
Registration,
|
||||||
|
@ -10,6 +7,9 @@ import {
|
||||||
ApiErrorWatcher,
|
ApiErrorWatcher,
|
||||||
} from '~/components/Auth';
|
} from '~/components/Auth';
|
||||||
import { AuthContextProvider } from '~/hooks/AuthContext';
|
import { AuthContextProvider } from '~/hooks/AuthContext';
|
||||||
|
import ChatRoute from './ChatRoute';
|
||||||
|
import Search from './Search';
|
||||||
|
import Root from './Root';
|
||||||
|
|
||||||
const AuthLayout = () => (
|
const AuthLayout = () => (
|
||||||
<AuthContextProvider>
|
<AuthContextProvider>
|
||||||
|
@ -50,10 +50,10 @@ export const router = createBrowserRouter([
|
||||||
path: 'c/:conversationId?',
|
path: 'c/:conversationId?',
|
||||||
element: <ChatRoute />,
|
element: <ChatRoute />,
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// path: 'search/:query?',
|
path: 'search',
|
||||||
// element: <Search />,
|
element: <Search />,
|
||||||
// },
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
useRecoilState,
|
useRecoilState,
|
||||||
useRecoilValue,
|
useRecoilValue,
|
||||||
useSetRecoilState,
|
useSetRecoilState,
|
||||||
|
useRecoilCallback,
|
||||||
} from 'recoil';
|
} from 'recoil';
|
||||||
import { LocalStorageKeys } from 'librechat-data-provider';
|
import { LocalStorageKeys } from 'librechat-data-provider';
|
||||||
import type { TMessage, TPreset, TConversation, TSubmission } from 'librechat-data-provider';
|
import type { TMessage, TPreset, TConversation, TSubmission } from 'librechat-data-provider';
|
||||||
|
@ -32,6 +33,10 @@ const conversationByIndex = atomFamily<TConversation | null, string | number>({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!newValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
storeEndpointSettings(newValue);
|
storeEndpointSettings(newValue);
|
||||||
localStorage.setItem(LocalStorageKeys.LAST_CONVO_SETUP, JSON.stringify(newValue));
|
localStorage.setItem(LocalStorageKeys.LAST_CONVO_SETUP, JSON.stringify(newValue));
|
||||||
});
|
});
|
||||||
|
@ -131,6 +136,29 @@ function useCreateConversationAtom(key: string | number) {
|
||||||
return { conversation, setConversation };
|
return { conversation, setConversation };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function useClearConvoState() {
|
||||||
|
const clearAllConversations = useRecoilCallback(
|
||||||
|
({ reset, snapshot }) =>
|
||||||
|
async () => {
|
||||||
|
const conversationKeys = await snapshot.getPromise(conversationKeysAtom);
|
||||||
|
|
||||||
|
for (const conversationKey of conversationKeys) {
|
||||||
|
reset(conversationByIndex(conversationKey));
|
||||||
|
|
||||||
|
const conversation = await snapshot.getPromise(conversationByIndex(conversationKey));
|
||||||
|
if (conversation) {
|
||||||
|
reset(latestMessageFamily(conversationKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset(conversationKeysAtom);
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
return clearAllConversations;
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
conversationByIndex,
|
conversationByIndex,
|
||||||
filesByIndex,
|
filesByIndex,
|
||||||
|
@ -146,6 +174,7 @@ export default {
|
||||||
showPopoverFamily,
|
showPopoverFamily,
|
||||||
latestMessageFamily,
|
latestMessageFamily,
|
||||||
allConversationsSelector,
|
allConversationsSelector,
|
||||||
|
useClearConvoState,
|
||||||
useCreateConversationAtom,
|
useCreateConversationAtom,
|
||||||
showMentionPopoverFamily,
|
showMentionPopoverFamily,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import { TMessage } from 'librechat-data-provider';
|
import { atom } from 'recoil';
|
||||||
import { atom, selector } from 'recoil';
|
|
||||||
import { buildTree } from '~/utils';
|
|
||||||
|
|
||||||
const isSearchEnabled = atom<boolean | null>({
|
const isSearchEnabled = atom<boolean | null>({
|
||||||
key: 'isSearchEnabled',
|
key: 'isSearchEnabled',
|
||||||
|
@ -12,30 +10,7 @@ const searchQuery = atom({
|
||||||
default: '',
|
default: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const searchResultMessages = atom<TMessage[] | null>({
|
|
||||||
key: 'searchResultMessages',
|
|
||||||
default: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
const searchResultMessagesTree = selector({
|
|
||||||
key: 'searchResultMessagesTree',
|
|
||||||
get: ({ get }) => {
|
|
||||||
return buildTree({ messages: get(searchResultMessages), groupAll: true });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const isSearching = selector({
|
|
||||||
key: 'isSearching',
|
|
||||||
get: ({ get }) => {
|
|
||||||
const data = get(searchQuery);
|
|
||||||
return !!data;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
isSearchEnabled,
|
isSearchEnabled,
|
||||||
isSearching,
|
|
||||||
searchResultMessages,
|
|
||||||
searchResultMessagesTree,
|
|
||||||
searchQuery,
|
searchQuery,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { convoData } from './convos.fakeData';
|
import { convoData } from './convos.fakeData';
|
||||||
import {
|
import {
|
||||||
groupConversationsByDate,
|
dateKeys,
|
||||||
addConversation,
|
addConversation,
|
||||||
updateConversation,
|
|
||||||
updateConvoFields,
|
updateConvoFields,
|
||||||
|
updateConversation,
|
||||||
deleteConversation,
|
deleteConversation,
|
||||||
findPageForConversation,
|
findPageForConversation,
|
||||||
|
groupConversationsByDate,
|
||||||
} from './convos';
|
} from './convos';
|
||||||
import type { TConversation, ConversationData } from 'librechat-data-provider';
|
import type { TConversation, ConversationData } from 'librechat-data-provider';
|
||||||
|
|
||||||
|
@ -20,13 +21,13 @@ describe('Conversation Utilities', () => {
|
||||||
{ conversationId: '5', updatedAt: new Date(Date.now() - 86400000 * 8).toISOString() }, // 8 days ago (previous 30 days)
|
{ conversationId: '5', updatedAt: new Date(Date.now() - 86400000 * 8).toISOString() }, // 8 days ago (previous 30 days)
|
||||||
];
|
];
|
||||||
const grouped = groupConversationsByDate(conversations as TConversation[]);
|
const grouped = groupConversationsByDate(conversations as TConversation[]);
|
||||||
expect(grouped[0][0]).toBe('Today');
|
expect(grouped[0][0]).toBe(dateKeys.today);
|
||||||
expect(grouped[0][1]).toHaveLength(1);
|
expect(grouped[0][1]).toHaveLength(1);
|
||||||
expect(grouped[1][0]).toBe('Yesterday');
|
expect(grouped[1][0]).toBe(dateKeys.yesterday);
|
||||||
expect(grouped[1][1]).toHaveLength(1);
|
expect(grouped[1][1]).toHaveLength(1);
|
||||||
expect(grouped[2][0]).toBe('Previous 7 days');
|
expect(grouped[2][0]).toBe(dateKeys.previous7Days);
|
||||||
expect(grouped[2][1]).toHaveLength(1);
|
expect(grouped[2][1]).toHaveLength(1);
|
||||||
expect(grouped[3][0]).toBe('Previous 30 days');
|
expect(grouped[3][0]).toBe(dateKeys.previous30Days);
|
||||||
expect(grouped[3][1]).toHaveLength(1);
|
expect(grouped[3][1]).toHaveLength(1);
|
||||||
expect(grouped[4][0]).toBe(' 2023');
|
expect(grouped[4][0]).toBe(' 2023');
|
||||||
expect(grouped[4][1]).toHaveLength(1);
|
expect(grouped[4][1]).toHaveLength(1);
|
||||||
|
|
|
@ -16,22 +16,42 @@ import type {
|
||||||
GroupedConversations,
|
GroupedConversations,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
|
|
||||||
|
export const dateKeys = {
|
||||||
|
today: 'com_ui_date_today',
|
||||||
|
yesterday: 'com_ui_date_yesterday',
|
||||||
|
previous7Days: 'com_ui_date_previous_7_days',
|
||||||
|
previous30Days: 'com_ui_date_previous_30_days',
|
||||||
|
january: 'com_ui_date_january',
|
||||||
|
february: 'com_ui_date_february',
|
||||||
|
march: 'com_ui_date_march',
|
||||||
|
april: 'com_ui_date_april',
|
||||||
|
may: 'com_ui_date_may',
|
||||||
|
june: 'com_ui_date_june',
|
||||||
|
july: 'com_ui_date_july',
|
||||||
|
august: 'com_ui_date_august',
|
||||||
|
september: 'com_ui_date_september',
|
||||||
|
october: 'com_ui_date_october',
|
||||||
|
november: 'com_ui_date_november',
|
||||||
|
december: 'com_ui_date_december',
|
||||||
|
};
|
||||||
|
|
||||||
const getGroupName = (date: Date) => {
|
const getGroupName = (date: Date) => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
if (isToday(date)) {
|
if (isToday(date)) {
|
||||||
return 'Today';
|
return dateKeys.today;
|
||||||
}
|
}
|
||||||
if (isWithinInterval(date, { start: startOfDay(subDays(now, 1)), end: now })) {
|
if (isWithinInterval(date, { start: startOfDay(subDays(now, 1)), end: now })) {
|
||||||
return 'Yesterday';
|
return dateKeys.yesterday;
|
||||||
}
|
}
|
||||||
if (isWithinInterval(date, { start: subDays(now, 7), end: now })) {
|
if (isWithinInterval(date, { start: subDays(now, 7), end: now })) {
|
||||||
return 'Previous 7 days';
|
return dateKeys.previous7Days;
|
||||||
}
|
}
|
||||||
if (isWithinInterval(date, { start: subDays(now, 30), end: now })) {
|
if (isWithinInterval(date, { start: subDays(now, 30), end: now })) {
|
||||||
return 'Previous 30 days';
|
return dateKeys.previous30Days;
|
||||||
}
|
}
|
||||||
if (isWithinInterval(date, { start: startOfYear(now), end: now })) {
|
if (isWithinInterval(date, { start: startOfYear(now), end: now })) {
|
||||||
return ' ' + format(date, 'MMMM');
|
const month = format(date, 'MMMM').toLowerCase();
|
||||||
|
return dateKeys[month];
|
||||||
}
|
}
|
||||||
return ' ' + getYear(date).toString();
|
return ' ' + getYear(date).toString();
|
||||||
};
|
};
|
||||||
|
@ -62,7 +82,12 @@ export const groupConversationsByDate = (conversations: TConversation[]): Groupe
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const sortedGroups = {};
|
const sortedGroups = {};
|
||||||
const dateGroups = ['Today', 'Last 7 days', 'Last 30 days'];
|
const dateGroups = [
|
||||||
|
dateKeys.today,
|
||||||
|
dateKeys.yesterday,
|
||||||
|
dateKeys.previous7Days,
|
||||||
|
dateKeys.previous30Days,
|
||||||
|
];
|
||||||
dateGroups.forEach((group) => {
|
dateGroups.forEach((group) => {
|
||||||
if (groups[group]) {
|
if (groups[group]) {
|
||||||
sortedGroups[group] = groups[group];
|
sortedGroups[group] = groups[group];
|
||||||
|
|
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -97,7 +97,7 @@
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
"pino": "^8.12.1",
|
"pino": "^8.12.1",
|
||||||
"sharp": "^0.32.6",
|
"sharp": "^0.32.6",
|
||||||
"tiktoken": "^1.0.10",
|
"tiktoken": "^1.0.15",
|
||||||
"traverse": "^0.6.7",
|
"traverse": "^0.6.7",
|
||||||
"ua-parser-js": "^1.0.36",
|
"ua-parser-js": "^1.0.36",
|
||||||
"winston": "^3.11.0",
|
"winston": "^3.11.0",
|
||||||
|
@ -26736,9 +26736,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tiktoken": {
|
"node_modules/tiktoken": {
|
||||||
"version": "1.0.13",
|
"version": "1.0.15",
|
||||||
"resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.15.tgz",
|
||||||
"integrity": "sha512-JaL9ZnvTbGFMDIBeGdVkLt4qWTeCPw+n7Ock+wceAGRenuHA6nOOvMJFliNDyXsjg2osGKJWsXtO2xc74VxyDw=="
|
"integrity": "sha512-sCsrq/vMWUSEW29CJLNmPvWxlVp7yh2tlkAjpJltIKqp5CKf98ZNpdeHRmAlPVFlGEbswDc6SmI8vz64W/qErw=="
|
||||||
},
|
},
|
||||||
"node_modules/timers-browserify": {
|
"node_modules/timers-browserify": {
|
||||||
"version": "2.0.12",
|
"version": "2.0.12",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue