mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 08:33:20 +00:00
(feat:settings)docs table design perfection
This commit is contained in:
@@ -15,7 +15,6 @@ import { Doc, DocumentsProps, ActiveState } from '../models/misc'; // Ensure Act
|
|||||||
import { getDocs, getDocsWithPagination } from '../preferences/preferenceApi';
|
import { getDocs, getDocsWithPagination } from '../preferences/preferenceApi';
|
||||||
import { setSourceDocs } from '../preferences/preferenceSlice';
|
import { setSourceDocs } from '../preferences/preferenceSlice';
|
||||||
import { setPaginatedDocuments } from '../preferences/preferenceSlice';
|
import { setPaginatedDocuments } from '../preferences/preferenceSlice';
|
||||||
import { truncate } from '../utils/stringUtils';
|
|
||||||
import { formatDate } from '../utils/dateTimeUtils';
|
import { formatDate } from '../utils/dateTimeUtils';
|
||||||
|
|
||||||
// Utility function to format numbers
|
// Utility function to format numbers
|
||||||
@@ -146,8 +145,8 @@ const Documents: React.FC<DocumentsProps> = ({
|
|||||||
}, [searchTerm]);
|
}, [searchTerm]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-8">
|
<div className="flex flex-col mt-8">
|
||||||
<div className="flex flex-col relative">
|
<div className="flex flex-col relative flex-grow">
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<h2 className="text-base font-medium text-sonic-silver">
|
<h2 className="text-base font-medium text-sonic-silver">
|
||||||
{t('settings.documents.title')}
|
{t('settings.documents.title')}
|
||||||
@@ -186,128 +185,135 @@ const Documents: React.FC<DocumentsProps> = ({
|
|||||||
{loading ? (
|
{loading ? (
|
||||||
<SkeletonLoader count={1} />
|
<SkeletonLoader count={1} />
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full overflow-x-auto rounded-md border border-silver dark:border-silver/40">
|
<div className="flex flex-col flex-grow">
|
||||||
<table className="w-full min-w-[640px] table-auto">
|
{' '}
|
||||||
<thead>
|
{/* Removed overflow-auto */}
|
||||||
<tr className="border-b border-silver dark:border-silver/40">
|
<div className="border rounded-md border-silver dark:border-silver/40">
|
||||||
<th className="py-3 px-4 text-left text-xs font-medium text-sonic-silver uppercase w-[45%]">
|
<table className="w-full min-w-[640px] table-auto">
|
||||||
{t('settings.documents.name')}
|
<thead>
|
||||||
</th>
|
<tr className="border-b border-silver dark:border-silver/40">
|
||||||
<th className="py-3 px-4 text-center text-xs font-medium text-sonic-silver uppercase w-[20%]">
|
<th className="py-3 px-4 text-left text-xs font-medium text-sonic-silver uppercase w-[45%]">
|
||||||
<div className="flex justify-center items-center">
|
{t('settings.documents.name')}
|
||||||
{t('settings.documents.date')}
|
</th>
|
||||||
<img
|
<th className="py-3 px-4 text-center text-xs font-medium text-sonic-silver uppercase w-[20%]">
|
||||||
className="cursor-pointer ml-2"
|
<div className="flex justify-center items-center">
|
||||||
onClick={() => refreshDocs('date')}
|
{t('settings.documents.date')}
|
||||||
src={caretSort}
|
<img
|
||||||
alt="sort"
|
className="cursor-pointer ml-2"
|
||||||
/>
|
onClick={() => refreshDocs('date')}
|
||||||
</div>
|
src={caretSort}
|
||||||
</th>
|
alt="sort"
|
||||||
<th className="py-3 px-4 text-center text-xs font-medium text-sonic-silver uppercase w-[25%]">
|
/>
|
||||||
<div className="flex justify-center items-center">
|
</div>
|
||||||
<span className="hidden sm:inline">
|
</th>
|
||||||
{t('settings.documents.tokenUsage')}
|
<th className="py-3 px-4 text-center text-xs font-medium text-sonic-silver uppercase w-[25%]">
|
||||||
|
<div className="flex justify-center items-center">
|
||||||
|
<span className="hidden sm:inline">
|
||||||
|
{t('settings.documents.tokenUsage')}
|
||||||
|
</span>
|
||||||
|
<span className="sm:hidden">
|
||||||
|
{t('settings.documents.tokenUsage')}
|
||||||
|
</span>
|
||||||
|
<img
|
||||||
|
className="cursor-pointer ml-2"
|
||||||
|
onClick={() => refreshDocs('tokens')}
|
||||||
|
src={caretSort}
|
||||||
|
alt="sort"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th className="py-3 px-4 text-right text-xs font-medium text-gray-700 dark:text-[#E0E0E0] uppercase w-[10%]">
|
||||||
|
<span className="sr-only">
|
||||||
|
{t('settings.documents.actions')}
|
||||||
</span>
|
</span>
|
||||||
<span className="sm:hidden">
|
</th>
|
||||||
{t('settings.documents.tokenUsage')}
|
|
||||||
</span>
|
|
||||||
<img
|
|
||||||
className="cursor-pointer ml-2"
|
|
||||||
onClick={() => refreshDocs('tokens')}
|
|
||||||
src={caretSort}
|
|
||||||
alt="sort"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
<th className="py-3 px-4 text-right text-xs font-medium text-gray-700 dark:text-[#E0E0E0] uppercase w-[10%]">
|
|
||||||
<span className="sr-only">
|
|
||||||
{t('settings.documents.actions')}
|
|
||||||
</span>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody className="divide-y divide-silver dark:divide-silver/40">
|
|
||||||
{!currentDocuments?.length && (
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
colSpan={4}
|
|
||||||
className="py-4 text-center text-gray-700 dark:text-[#E0E0E0]"
|
|
||||||
>
|
|
||||||
{t('settings.documents.noData')}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
</thead>
|
||||||
{Array.isArray(currentDocuments) &&
|
<tbody className="divide-y divide-silver dark:divide-silver/40">
|
||||||
currentDocuments.map((document, index) => (
|
{!currentDocuments?.length ? (
|
||||||
<tr key={index}>
|
<tr>
|
||||||
<td className="py-4 px-4 text-sm text-gray-700 dark:text-[#E0E0E0] w-[45%]">
|
<td
|
||||||
<div
|
colSpan={4}
|
||||||
className="overflow-hidden text-ellipsis whitespace-nowrap"
|
className="py-4 text-center text-gray-700 dark:text-[#E0E0E0] bg-white dark:bg-transparent"
|
||||||
title={document.name}
|
>
|
||||||
>
|
{t('settings.documents.noData')}
|
||||||
{truncate(document.name, 50)}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td className="py-4 px-4 text-center text-sm text-gray-700 dark:text-[#E0E0E0] whitespace-nowrap w-[20%]">
|
|
||||||
{document.date ? formatDate(document.date) : ''}
|
|
||||||
</td>
|
|
||||||
<td className="py-4 px-4 text-center text-sm text-gray-700 dark:text-[#E0E0E0] whitespace-nowrap w-[25%]">
|
|
||||||
{document.tokens ? formatTokens(+document.tokens) : ''}
|
|
||||||
</td>
|
|
||||||
<td className="py-4 px-4 text-right w-[10%]">
|
|
||||||
<div className="flex items-center justify-end gap-3">
|
|
||||||
{/* For non-remote documents, adding empty space holder */}
|
|
||||||
{!document.syncFrequency && (
|
|
||||||
<div className="w-8"></div>
|
|
||||||
)}
|
|
||||||
{document.syncFrequency && (
|
|
||||||
<DropdownMenu
|
|
||||||
name={t('settings.documents.sync')}
|
|
||||||
options={syncOptions}
|
|
||||||
onSelect={(value: string) => {
|
|
||||||
handleManageSync(document, value);
|
|
||||||
}}
|
|
||||||
defaultValue={document.syncFrequency}
|
|
||||||
icon={SyncIcon}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<button
|
|
||||||
onClick={(event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
handleDeleteDocument(index, document);
|
|
||||||
}}
|
|
||||||
className="inline-flex items-center justify-center w-8 h-8 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors flex-shrink-0"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={Trash}
|
|
||||||
alt={t('convTile.delete')}
|
|
||||||
className="h-4 w-4 opacity-60 hover:opacity-100"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
) : (
|
||||||
</tbody>
|
currentDocuments.map((document, index) => (
|
||||||
</table>
|
<tr key={index} className="bg-white dark:bg-transparent">
|
||||||
|
<td
|
||||||
|
className="py-4 px-4 text-sm text-gray-700 dark:text-[#E0E0E0] w-[45%] truncate"
|
||||||
|
title={document.name}
|
||||||
|
>
|
||||||
|
{document.name}
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-4 text-center text-sm text-gray-700 dark:text-[#E0E0E0] whitespace-nowrap w-[20%]">
|
||||||
|
{document.date ? formatDate(document.date) : ''}
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-4 text-center text-sm text-gray-700 dark:text-[#E0E0E0] whitespace-nowrap w-[25%]">
|
||||||
|
{document.tokens
|
||||||
|
? formatTokens(+document.tokens)
|
||||||
|
: ''}
|
||||||
|
</td>
|
||||||
|
<td className="py-4 px-4 text-right w-[10%]">
|
||||||
|
<div className="flex items-center justify-end gap-3">
|
||||||
|
{!document.syncFrequency && (
|
||||||
|
<div className="w-8"></div>
|
||||||
|
)}
|
||||||
|
{document.syncFrequency && (
|
||||||
|
<DropdownMenu
|
||||||
|
name={t('settings.documents.sync')}
|
||||||
|
options={syncOptions}
|
||||||
|
onSelect={(value: string) => {
|
||||||
|
handleManageSync(document, value);
|
||||||
|
}}
|
||||||
|
defaultValue={document.syncFrequency}
|
||||||
|
icon={SyncIcon}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
handleDeleteDocument(index, document);
|
||||||
|
}}
|
||||||
|
className="inline-flex items-center justify-center w-8 h-8 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors flex-shrink-0"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={Trash}
|
||||||
|
alt={t('convTile.delete')}
|
||||||
|
className="h-4 w-4 opacity-60 hover:opacity-100"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Pagination
|
|
||||||
currentPage={currentPage}
|
<div className="mt-auto pt-4">
|
||||||
totalPages={totalPages}
|
<Pagination
|
||||||
rowsPerPage={rowsPerPage}
|
currentPage={currentPage}
|
||||||
onPageChange={(page) => {
|
totalPages={totalPages}
|
||||||
setCurrentPage(page);
|
rowsPerPage={rowsPerPage}
|
||||||
refreshDocs(undefined, page, rowsPerPage);
|
onPageChange={(page) => {
|
||||||
}}
|
setCurrentPage(page);
|
||||||
onRowsPerPageChange={(rows) => {
|
refreshDocs(undefined, page, rowsPerPage);
|
||||||
setRowsPerPage(rows);
|
}}
|
||||||
setCurrentPage(1);
|
onRowsPerPageChange={(rows) => {
|
||||||
refreshDocs(undefined, 1, rows);
|
setRowsPerPage(rows);
|
||||||
}}
|
setCurrentPage(1);
|
||||||
/>
|
refreshDocs(undefined, 1, rows);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{modalState === 'ACTIVE' && (
|
{modalState === 'ACTIVE' && (
|
||||||
<Upload
|
<Upload
|
||||||
receivedFile={[]}
|
receivedFile={[]}
|
||||||
|
|||||||
Reference in New Issue
Block a user