diff --git a/src/App.tsx b/src/App.tsx index 59e8583..85281b3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -49,6 +49,7 @@ function App() { }> + } /> } /> } /> } /> diff --git a/src/components/Dateien/dateienLogic.tsx b/src/components/Dateien/dateienLogic.tsx index 01b9948..f86c171 100644 --- a/src/components/Dateien/dateienLogic.tsx +++ b/src/components/Dateien/dateienLogic.tsx @@ -128,7 +128,7 @@ export function useDateienLogic(): DateienLogicReturn { const columns: ColumnConfig[] = useMemo(() => [ { key: 'file_name', - label: 'Filename', + label: t('files.column.filename'), type: 'string', width: 300, minWidth: 200, @@ -144,8 +144,7 @@ export function useDateienLogic(): DateienLogicReturn { display: 'block', whiteSpace: 'nowrap', overflow: 'hidden', - textOverflow: 'ellipsis', - paddingLeft: '8px' + textOverflow: 'ellipsis' }} title={value} > @@ -155,7 +154,7 @@ export function useDateienLogic(): DateienLogicReturn { }, { key: 'mime_type', - label: 'mime type', + label: t('files.column.mimetype'), type: 'string', width: 200, minWidth: 150, @@ -166,7 +165,7 @@ export function useDateienLogic(): DateienLogicReturn { }, { key: 'size', - label: 'filesize', + label: t('files.column.filesize'), type: 'number', width: 140, minWidth: 120, @@ -181,7 +180,7 @@ export function useDateienLogic(): DateienLogicReturn { }, { key: 'created_at', - label: 'creation date', + label: t('files.column.creationdate'), type: 'date', width: 200, minWidth: 180, @@ -190,7 +189,7 @@ export function useDateienLogic(): DateienLogicReturn { filterable: true, formatter: (value: string | undefined) => formatDate(value) }, - ], []); + ], [t]); // Handle file download const handleDownload = async (file: UserFile) => { diff --git a/src/components/FormGenerator/FormGenerator.module.css b/src/components/FormGenerator/FormGenerator.module.css index 2d462bb..fda1980 100644 --- a/src/components/FormGenerator/FormGenerator.module.css +++ b/src/components/FormGenerator/FormGenerator.module.css @@ -397,7 +397,7 @@ tbody .actionsColumn { /* Pagination */ .pagination { display: flex; - justify-content: center; + justify-content: space-between; align-items: center; gap: 10px; padding: 15px; @@ -406,6 +406,37 @@ tbody .actionsColumn { border-radius: 0 0 8px 8px; } +.pageSizeSelector { + display: flex; + align-items: center; + gap: 8px; + font-size: 14px; + color: var(--color-text); +} + +.pageSizeSelector label { + white-space: nowrap; + font-family: var(--font-family); +} + +.pageSizeSelect { + height: 32px; + padding: 4px 8px; + border: 1px solid var(--color-primary); + border-radius: 4px; + font-size: 14px; + font-family: var(--font-family); + background: var(--color-bg); + color: var(--color-text); + cursor: pointer; + min-width: 60px; +} + +.pageSizeSelect:focus { + outline: none; + border-color: var(--color-secondary); +} + .paginationButton { padding: 8px 12px; border: 1px solid var(--color-gray-disabled); @@ -490,16 +521,19 @@ tbody .actionsColumn { } .pagination { - flex-wrap: wrap; - gap: 5px; + flex-direction: column; + gap: 10px; padding: 10px; } - .paginationInfo { + .pageSizeSelector { order: -1; - width: 100%; + justify-content: center; + } + + .paginationInfo { text-align: center; - margin: 0 0 10px 0; + margin: 0; font-size: 13px; } } diff --git a/src/components/FormGenerator/FormGenerator.tsx b/src/components/FormGenerator/FormGenerator.tsx index abc26d5..4c89f02 100644 --- a/src/components/FormGenerator/FormGenerator.tsx +++ b/src/components/FormGenerator/FormGenerator.tsx @@ -27,6 +27,8 @@ export interface FormGeneratorProps { resizable?: boolean; pagination?: boolean; pageSize?: number; + pageSizeOptions?: number[]; + showPageSizeSelector?: boolean; onRowClick?: (row: T, index: number) => void; onRowSelect?: (selectedRows: T[]) => void; selectable?: boolean; @@ -49,6 +51,8 @@ export function FormGenerator>({ resizable = true, pagination = true, pageSize = 10, + pageSizeOptions = [10, 25, 50, 100], + showPageSizeSelector = true, onRowClick, onRowSelect, selectable = false, @@ -100,6 +104,7 @@ export function FormGenerator>({ const [columnWidths, setColumnWidths] = useState>({}); const [selectedRows, setSelectedRows] = useState>(new Set()); const [currentPage, setCurrentPage] = useState(1); + const [currentPageSize, setCurrentPageSize] = useState(pageSize); // Refs for resizing const tableRef = useRef(null); @@ -188,11 +193,11 @@ export function FormGenerator>({ const paginatedData = useMemo(() => { if (!pagination) return filteredData; - const startIndex = (currentPage - 1) * pageSize; - return filteredData.slice(startIndex, startIndex + pageSize); - }, [filteredData, currentPage, pageSize, pagination]); + const startIndex = (currentPage - 1) * currentPageSize; + return filteredData.slice(startIndex, startIndex + currentPageSize); + }, [filteredData, currentPage, currentPageSize, pagination]); - const totalPages = Math.ceil(filteredData.length / pageSize); + const totalPages = Math.ceil(filteredData.length / currentPageSize); // Handle sorting const handleSort = (key: string) => { @@ -257,6 +262,12 @@ export function FormGenerator>({ } }; + // Handle page size change + const handlePageSizeChange = (newPageSize: number) => { + setCurrentPageSize(newPageSize); + setCurrentPage(1); // Reset to first page when page size changes + }; + // Handle column resizing const handleMouseDown = (e: React.MouseEvent, columnKey: string) => { if (!resizable) return; @@ -333,6 +344,7 @@ export function FormGenerator>({ return (
+ {title &&

{title}

} {(searchable || filterable) && ( @@ -640,48 +652,68 @@ export function FormGenerator>({
{/* Pagination */} - {pagination && totalPages > 1 && ( + {pagination && (
- - + {showPageSizeSelector && ( +
+ + +
+ )} - - {t('formgen.pagination.info') - .replace('{page}', currentPage.toString()) - .replace('{total}', totalPages.toString()) - .replace('{count}', filteredData.length.toString())} - - - - + {totalPages > 1 && ( + <> + + + + + {t('formgen.pagination.info') + .replace('{page}', currentPage.toString()) + .replace('{total}', totalPages.toString()) + .replace('{count}', filteredData.length.toString())} + + + + + + )}
)} diff --git a/src/locales/de.ts b/src/locales/de.ts index 6daf96d..8c420b2 100644 --- a/src/locales/de.ts +++ b/src/locales/de.ts @@ -267,9 +267,13 @@ export default { // File Table Columns 'files.column.name': 'Name', + 'files.column.filename': 'Dateiname', 'files.column.type': 'Typ', + 'files.column.mimetype': 'MIME-Typ', 'files.column.size': 'Größe', + 'files.column.filesize': 'Dateigröße', 'files.column.created': 'Erstellt', + 'files.column.creationdate': 'Erstellungsdatum', 'files.column.source': 'Quelle', // File Types @@ -334,6 +338,7 @@ export default { 'formgen.filter.placeholder': '{column} filtern', 'formgen.actions.column': 'Aktionen', 'formgen.pagination.info': 'Seite {page} von {total} ({count} Einträge)', + 'formgen.pagination.pageSize': 'Einträge pro Seite:', 'formgen.pagination.first': 'Erste Seite', 'formgen.pagination.prev': 'Vorherige Seite', 'formgen.pagination.next': 'Nächste Seite', diff --git a/src/locales/en.ts b/src/locales/en.ts index 32f7a50..09c4a44 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -268,9 +268,13 @@ export default { // File Table Columns 'files.column.name': 'Name', + 'files.column.filename': 'Filename', 'files.column.type': 'Type', + 'files.column.mimetype': 'MIME Type', 'files.column.size': 'Size', + 'files.column.filesize': 'File Size', 'files.column.created': 'Created', + 'files.column.creationdate': 'Creation Date', 'files.column.source': 'Source', // File Types @@ -335,6 +339,7 @@ export default { 'formgen.filter.placeholder': 'Filter {column}', 'formgen.actions.column': 'Actions', 'formgen.pagination.info': 'Page {page} of {total} ({count} items)', + 'formgen.pagination.pageSize': 'Items per page:', 'formgen.pagination.first': 'First page', 'formgen.pagination.prev': 'Previous page', 'formgen.pagination.next': 'Next page', diff --git a/src/locales/fr.ts b/src/locales/fr.ts index d7806e7..d4ef499 100644 --- a/src/locales/fr.ts +++ b/src/locales/fr.ts @@ -267,9 +267,13 @@ export default { // File Table Columns 'files.column.name': 'Nom', + 'files.column.filename': 'Nom de fichier', 'files.column.type': 'Type', + 'files.column.mimetype': 'Type MIME', 'files.column.size': 'Taille', + 'files.column.filesize': 'Taille du fichier', 'files.column.created': 'Créé', + 'files.column.creationdate': 'Date de création', 'files.column.source': 'Source', // File Types @@ -334,6 +338,7 @@ export default { 'formgen.filter.placeholder': 'Filtrer {column}', 'formgen.actions.column': 'Actions', 'formgen.pagination.info': 'Page {page} sur {total} ({count} éléments)', + 'formgen.pagination.pageSize': 'Éléments par page:', 'formgen.pagination.first': 'Première page', 'formgen.pagination.prev': 'Page précédente', 'formgen.pagination.next': 'Page suivante', diff --git a/src/pages/Home/Dashboard.tsx b/src/pages/Home/Dashboard.tsx index 48ba38a..b06b7a9 100644 --- a/src/pages/Home/Dashboard.tsx +++ b/src/pages/Home/Dashboard.tsx @@ -7,6 +7,8 @@ function Dashboard () { const [isChatExpanded, setIsChatExpanded] = useState(false); const [selectedPrompt, setSelectedPrompt] = useState(null); const [isPromptAreaCollapsed, setIsPromptAreaCollapsed] = useState(false); + const [currentWorkflowId, setCurrentWorkflowId] = useState(null); + const [workflowCompleted, setWorkflowCompleted] = useState(false); const handleChatToggleExpand = () => { setIsChatExpanded(!isChatExpanded); @@ -25,7 +27,7 @@ function Dashboard () { } return workflowId; }); - }, []); + }, [setCurrentWorkflowId, setWorkflowCompleted]); const handleWorkflowCompletedChange = useCallback((completed: boolean) => { setWorkflowCompleted(completed); @@ -62,11 +64,3 @@ function Dashboard () { } export default Dashboard; - -function setCurrentWorkflowId(arg0: (prevId: any) => string | null) { - throw new Error('Function not implemented.'); -} - -function setWorkflowCompleted(arg0: boolean) { - throw new Error('Function not implemented.'); -}