This commit is contained in:
GH Action - Upstream Sync
2025-02-20 01:21:11 +00:00
9 changed files with 254 additions and 211 deletions

View File

@@ -538,11 +538,12 @@ function DocumentChunks({
</div>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
{paginatedChunks.filter((chunk) =>
chunk.metadata?.title
{paginatedChunks.filter((chunk) => {
if (!chunk.metadata?.title) return true;
return chunk.metadata.title
.toLowerCase()
.includes(searchTerm.toLowerCase()),
).length === 0 ? (
.includes(searchTerm.toLowerCase());
}).length === 0 ? (
<div className="mt-24 col-span-2 lg:col-span-3 text-center text-gray-500 dark:text-gray-400">
<img
src={isDarkTheme ? NoFilesDarkIcon : NoFilesIcon}
@@ -553,11 +554,12 @@ function DocumentChunks({
</div>
) : (
paginatedChunks
.filter((chunk) =>
chunk.metadata?.title
.filter((chunk) => {
if (!chunk.metadata?.title) return true;
return chunk.metadata.title
.toLowerCase()
.includes(searchTerm.toLowerCase()),
)
.includes(searchTerm.toLowerCase());
})
.map((chunk, index) => (
<div
key={index}
@@ -584,7 +586,7 @@ function DocumentChunks({
</div>
<div className="mt-[9px]">
<p className="h-12 text-sm font-semibold text-eerie-black dark:text-[#EEEEEE] leading-relaxed break-words ellipsis-text">
{chunk.metadata?.title}
{chunk.metadata?.title ?? 'Untitled'}
</p>
<p className="mt-1 pr-1 h-[110px] overflow-y-auto text-[13px] text-gray-600 dark:text-gray-400 leading-relaxed break-words">
{chunk.text}
@@ -597,11 +599,12 @@ function DocumentChunks({
</div>
)}
{!loading &&
paginatedChunks.filter((chunk) =>
chunk.metadata?.title
paginatedChunks.filter((chunk) => {
if (!chunk.metadata?.title) return true;
return chunk.metadata.title
.toLowerCase()
.includes(searchTerm.toLowerCase()),
).length !== 0 && (
.includes(searchTerm.toLowerCase());
}).length !== 0 && (
<div className="mt-10 w-full flex items-center justify-center">
<Pagination
currentPage={page}

View File

@@ -84,7 +84,7 @@ export default function General() {
return (
<div className="mt-12">
<div className="mb-5">
<label className="block font-bold text-jet dark:text-bright-gray">
<label className="block mb-2 font-bold text-jet dark:text-bright-gray">
{t('settings.general.selectTheme')}
</label>
<Dropdown

View File

@@ -3,11 +3,11 @@ import { useTranslation } from 'react-i18next';
import userService from '../api/services/userService';
import ChevronRight from '../assets/chevron-right.svg';
import CopyButton from '../components/CopyButton';
import Dropdown from '../components/Dropdown';
import SkeletonLoader from '../components/SkeletonLoader';
import { APIKeyData, LogData } from './types';
import CoppyButton from '../components/CopyButton';
import { useLoaderState } from '../hooks';
import { APIKeyData, LogData } from './types';
export default function Logs() {
const { t } = useTranslation();
@@ -148,7 +148,7 @@ function LogsTable({ logs, setPage, loading }: LogsTableProps) {
{logs?.map((log, index) => {
if (index === logs.length - 1) {
return (
<div ref={firstObserver} key={index}>
<div ref={firstObserver} key={index} className="w-full">
<Log log={log} />
</div>
);
@@ -170,26 +170,30 @@ function Log({ log }: { log: LogData }) {
const { id, action, timestamp, ...filteredLog } = log;
return (
<details className="group bg-transparent [&_summary::-webkit-details-marker]:hidden w-full hover:bg-[#F9F9F9] hover:dark:bg-dark-charcoal">
<summary className="flex flex-row items-center gap-2 text-gray-900 cursor-pointer p-2 group-open:bg-[#F9F9F9] dark:group-open:bg-dark-charcoal">
<summary className="flex flex-row items-start gap-2 text-gray-900 cursor-pointer p-2 group-open:bg-[#F9F9F9] dark:group-open:bg-dark-charcoal">
<img
src={ChevronRight}
alt="Expand log entry"
className="w-3 h-3 transition duration-300 group-open:rotate-90"
className="mt-[3px] w-3 h-3 transition duration-300 group-open:rotate-90"
/>
<span className="flex flex-row gap-2">
<h2 className="text-xs text-black/60 dark:text-bright-gray">{`${log.timestamp}`}</h2>
<h2 className="text-xs text-[#913400] dark:text-[#DF5200]">{`[${log.action}]`}</h2>
<h2
className={`text-xs ${logLevelColor[log.level]}`}
>{`${log.question}`}</h2>
className={`max-w-72 text-xs ${logLevelColor[log.level]} break-words`}
>
{`${log.question}`.length > 250
? `${log.question.substring(0, 250)}...`
: log.question}
</h2>
</span>
</summary>
<div className="px-4 group-open:bg-[#F9F9F9] dark:group-open:bg-dark-charcoal">
<p className="px-2 leading-relaxed text-gray-700 dark:text-gray-400 text-xs">
<p className="px-2 leading-relaxed text-gray-700 dark:text-gray-400 text-xs break-words">
{JSON.stringify(filteredLog, null, 2)}
</p>
<div className="my-px w-8">
<CoppyButton
<CopyButton
text={JSON.stringify(filteredLog)}
colorLight="transparent"
/>

View File

@@ -6,6 +6,7 @@ import CogwheelIcon from '../assets/cogwheel.svg';
import NoFilesDarkIcon from '../assets/no-files-dark.svg';
import NoFilesIcon from '../assets/no-files.svg';
import Input from '../components/Input';
import Spinner from '../components/Spinner';
import { useDarkTheme } from '../hooks';
import AddToolModal from '../modals/AddToolModal';
import { ActiveState } from '../models/misc';
@@ -22,8 +23,10 @@ export default function Tools() {
const [selectedTool, setSelectedTool] = React.useState<
UserToolType | APIToolType | null
>(null);
const [loading, setLoading] = React.useState(false);
const getUserTools = () => {
setLoading(true);
userService
.getUserTools()
.then((res) => {
@@ -31,6 +34,11 @@ export default function Tools() {
})
.then((data) => {
setUserTools(data.tools);
setLoading(false);
})
.catch((error) => {
console.error('Error fetching tools:', error);
setLoading(false);
});
};
@@ -78,7 +86,6 @@ export default function Tools() {
React.useEffect(() => {
getUserTools();
}, []);
return (
<div>
{selectedTool ? (
@@ -115,88 +122,99 @@ export default function Tools() {
{t('settings.tools.addTool')}
</button>
</div>
<div className="grid grid-cols-2 lg:grid-cols-3 gap-6">
{userTools.filter((tool) =>
tool.displayName
.toLowerCase()
.includes(searchTerm.toLowerCase()),
).length === 0 ? (
<div className="mt-24 col-span-2 lg:col-span-3 text-center text-gray-500 dark:text-gray-400">
<img
src={isDarkTheme ? NoFilesDarkIcon : NoFilesIcon}
alt="No tools found"
className="h-24 w-24 mx-auto mb-2"
/>
{t('settings.tools.noToolsFound')}
{loading ? (
<div className="grid grid-cols-2 lg:grid-cols-3 gap-6">
<div className="mt-24 h-32 col-span-2 lg:col-span-3 flex items-center justify-center">
<Spinner />
</div>
) : (
userTools
.filter((tool) =>
tool.displayName
.toLowerCase()
.includes(searchTerm.toLowerCase()),
)
.map((tool, index) => (
<div
key={index}
className="relative h-56 w-full p-6 border rounded-2xl border-silver dark:border-silver/40 flex flex-col justify-between"
>
<div className="w-full">
<div className="w-full flex items-center justify-between">
<img
src={`/toolIcons/tool_${tool.name}.svg`}
alt={`${tool.displayName} icon`}
className="h-8 w-8"
/>
<button
className="absolute top-3 right-3 cursor-pointer"
onClick={() => handleSettingsClick(tool)}
aria-label={t('settings.tools.configureToolAria', {
toolName: tool.displayName,
})}
>
</div>
) : (
<div className="grid grid-cols-2 lg:grid-cols-3 gap-6">
{userTools.filter((tool) =>
tool.displayName
.toLowerCase()
.includes(searchTerm.toLowerCase()),
).length === 0 ? (
<div className="mt-24 col-span-2 lg:col-span-3 text-center text-gray-500 dark:text-gray-400">
<img
src={isDarkTheme ? NoFilesDarkIcon : NoFilesIcon}
alt="No tools found"
className="h-24 w-24 mx-auto mb-2"
/>
{t('settings.tools.noToolsFound')}
</div>
) : (
userTools
.filter((tool) =>
tool.displayName
.toLowerCase()
.includes(searchTerm.toLowerCase()),
)
.map((tool, index) => (
<div
key={index}
className="relative h-56 w-full p-6 border rounded-2xl border-silver dark:border-silver/40 flex flex-col justify-between"
>
<div className="w-full">
<div className="w-full flex items-center justify-between">
<img
src={CogwheelIcon}
alt={t('settings.tools.settingsIconAlt')}
className="h-[19px] w-[19px]"
src={`/toolIcons/tool_${tool.name}.svg`}
alt={`${tool.displayName} icon`}
className="h-8 w-8"
/>
</button>
<button
className="absolute top-3 right-3 cursor-pointer"
onClick={() => handleSettingsClick(tool)}
aria-label={t(
'settings.tools.configureToolAria',
{
toolName: tool.displayName,
},
)}
>
<img
src={CogwheelIcon}
alt={t('settings.tools.settingsIconAlt')}
className="h-[19px] w-[19px]"
/>
</button>
</div>
<div className="mt-[9px]">
<p className="text-sm font-semibold text-eerie-black dark:text-[#EEEEEE] leading-relaxed">
{tool.displayName}
</p>
<p className="mt-1 h-16 overflow-auto text-[13px] text-gray-600 dark:text-gray-400 leading-relaxed pr-1">
{tool.description}
</p>
</div>
</div>
<div className="mt-[9px]">
<p className="text-sm font-semibold text-eerie-black dark:text-[#EEEEEE] leading-relaxed">
{tool.displayName}
</p>
<p className="mt-1 h-16 overflow-auto text-[13px] text-gray-600 dark:text-gray-400 leading-relaxed pr-1">
{tool.description}
</p>
<div className="absolute bottom-3 right-3">
<label
htmlFor={`toolToggle-${index}`}
className="relative inline-block h-6 w-10 cursor-pointer rounded-full bg-gray-300 dark:bg-[#D2D5DA33]/20 transition [-webkit-tap-highlight-color:_transparent] has-[:checked]:bg-[#0C9D35CC] has-[:checked]:dark:bg-[#0C9D35CC]"
>
<span className="sr-only">
{t('settings.tools.toggleToolAria', {
toolName: tool.displayName,
})}
</span>
<input
type="checkbox"
id={`toolToggle-${index}`}
className="peer sr-only"
checked={tool.status}
onChange={() =>
updateToolStatus(tool.id, !tool.status)
}
/>
<span className="absolute inset-y-0 start-0 m-[3px] size-[18px] rounded-full bg-white transition-all peer-checked:start-4"></span>
</label>
</div>
</div>
<div className="absolute bottom-3 right-3">
<label
htmlFor={`toolToggle-${index}`}
className="relative inline-block h-6 w-10 cursor-pointer rounded-full bg-gray-300 dark:bg-[#D2D5DA33]/20 transition [-webkit-tap-highlight-color:_transparent] has-[:checked]:bg-[#0C9D35CC] has-[:checked]:dark:bg-[#0C9D35CC]"
>
<span className="sr-only">
{t('settings.tools.toggleToolAria', {
toolName: tool.displayName,
})}
</span>
<input
type="checkbox"
id={`toolToggle-${index}`}
className="peer sr-only"
checked={tool.status}
onChange={() =>
updateToolStatus(tool.id, !tool.status)
}
/>
<span className="absolute inset-y-0 start-0 m-[3px] size-[18px] rounded-full bg-white transition-all peer-checked:start-4"></span>
</label>
</div>
</div>
))
)}
</div>
))
)}
</div>
)}
</div>
<AddToolModal
message={t('settings.tools.selectToolSetup')}