added dateien page
This commit is contained in:
parent
7cbdb0aea5
commit
10c7073cce
8 changed files with 141 additions and 66 deletions
|
|
@ -49,6 +49,7 @@ function App() {
|
||||||
<Home />
|
<Home />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
}>
|
}>
|
||||||
|
<Route index element={<Dashboard />} />
|
||||||
<Route path="dashboard" element={<Dashboard />} />
|
<Route path="dashboard" element={<Dashboard />} />
|
||||||
<Route path="dateien" element={<Dateien />} />
|
<Route path="dateien" element={<Dateien />} />
|
||||||
<Route path="team-bereich" element={<TeamBereich />} />
|
<Route path="team-bereich" element={<TeamBereich />} />
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ export function useDateienLogic(): DateienLogicReturn {
|
||||||
const columns: ColumnConfig[] = useMemo(() => [
|
const columns: ColumnConfig[] = useMemo(() => [
|
||||||
{
|
{
|
||||||
key: 'file_name',
|
key: 'file_name',
|
||||||
label: 'Filename',
|
label: t('files.column.filename'),
|
||||||
type: 'string',
|
type: 'string',
|
||||||
width: 300,
|
width: 300,
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
|
|
@ -144,8 +144,7 @@ export function useDateienLogic(): DateienLogicReturn {
|
||||||
display: 'block',
|
display: 'block',
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis'
|
||||||
paddingLeft: '8px'
|
|
||||||
}}
|
}}
|
||||||
title={value}
|
title={value}
|
||||||
>
|
>
|
||||||
|
|
@ -155,7 +154,7 @@ export function useDateienLogic(): DateienLogicReturn {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'mime_type',
|
key: 'mime_type',
|
||||||
label: 'mime type',
|
label: t('files.column.mimetype'),
|
||||||
type: 'string',
|
type: 'string',
|
||||||
width: 200,
|
width: 200,
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
|
|
@ -166,7 +165,7 @@ export function useDateienLogic(): DateienLogicReturn {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'size',
|
key: 'size',
|
||||||
label: 'filesize',
|
label: t('files.column.filesize'),
|
||||||
type: 'number',
|
type: 'number',
|
||||||
width: 140,
|
width: 140,
|
||||||
minWidth: 120,
|
minWidth: 120,
|
||||||
|
|
@ -181,7 +180,7 @@ export function useDateienLogic(): DateienLogicReturn {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'created_at',
|
key: 'created_at',
|
||||||
label: 'creation date',
|
label: t('files.column.creationdate'),
|
||||||
type: 'date',
|
type: 'date',
|
||||||
width: 200,
|
width: 200,
|
||||||
minWidth: 180,
|
minWidth: 180,
|
||||||
|
|
@ -190,7 +189,7 @@ export function useDateienLogic(): DateienLogicReturn {
|
||||||
filterable: true,
|
filterable: true,
|
||||||
formatter: (value: string | undefined) => formatDate(value)
|
formatter: (value: string | undefined) => formatDate(value)
|
||||||
},
|
},
|
||||||
], []);
|
], [t]);
|
||||||
|
|
||||||
// Handle file download
|
// Handle file download
|
||||||
const handleDownload = async (file: UserFile) => {
|
const handleDownload = async (file: UserFile) => {
|
||||||
|
|
|
||||||
|
|
@ -397,7 +397,7 @@ tbody .actionsColumn {
|
||||||
/* Pagination */
|
/* Pagination */
|
||||||
.pagination {
|
.pagination {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
|
@ -406,6 +406,37 @@ tbody .actionsColumn {
|
||||||
border-radius: 0 0 8px 8px;
|
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 {
|
.paginationButton {
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
border: 1px solid var(--color-gray-disabled);
|
border: 1px solid var(--color-gray-disabled);
|
||||||
|
|
@ -490,16 +521,19 @@ tbody .actionsColumn {
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination {
|
.pagination {
|
||||||
flex-wrap: wrap;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.paginationInfo {
|
.pageSizeSelector {
|
||||||
order: -1;
|
order: -1;
|
||||||
width: 100%;
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paginationInfo {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0 0 10px 0;
|
margin: 0;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ export interface FormGeneratorProps<T = any> {
|
||||||
resizable?: boolean;
|
resizable?: boolean;
|
||||||
pagination?: boolean;
|
pagination?: boolean;
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
|
pageSizeOptions?: number[];
|
||||||
|
showPageSizeSelector?: boolean;
|
||||||
onRowClick?: (row: T, index: number) => void;
|
onRowClick?: (row: T, index: number) => void;
|
||||||
onRowSelect?: (selectedRows: T[]) => void;
|
onRowSelect?: (selectedRows: T[]) => void;
|
||||||
selectable?: boolean;
|
selectable?: boolean;
|
||||||
|
|
@ -49,6 +51,8 @@ export function FormGenerator<T extends Record<string, any>>({
|
||||||
resizable = true,
|
resizable = true,
|
||||||
pagination = true,
|
pagination = true,
|
||||||
pageSize = 10,
|
pageSize = 10,
|
||||||
|
pageSizeOptions = [10, 25, 50, 100],
|
||||||
|
showPageSizeSelector = true,
|
||||||
onRowClick,
|
onRowClick,
|
||||||
onRowSelect,
|
onRowSelect,
|
||||||
selectable = false,
|
selectable = false,
|
||||||
|
|
@ -100,6 +104,7 @@ export function FormGenerator<T extends Record<string, any>>({
|
||||||
const [columnWidths, setColumnWidths] = useState<Record<string, number>>({});
|
const [columnWidths, setColumnWidths] = useState<Record<string, number>>({});
|
||||||
const [selectedRows, setSelectedRows] = useState<Set<number>>(new Set());
|
const [selectedRows, setSelectedRows] = useState<Set<number>>(new Set());
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [currentPageSize, setCurrentPageSize] = useState(pageSize);
|
||||||
|
|
||||||
// Refs for resizing
|
// Refs for resizing
|
||||||
const tableRef = useRef<HTMLTableElement>(null);
|
const tableRef = useRef<HTMLTableElement>(null);
|
||||||
|
|
@ -188,11 +193,11 @@ export function FormGenerator<T extends Record<string, any>>({
|
||||||
const paginatedData = useMemo(() => {
|
const paginatedData = useMemo(() => {
|
||||||
if (!pagination) return filteredData;
|
if (!pagination) return filteredData;
|
||||||
|
|
||||||
const startIndex = (currentPage - 1) * pageSize;
|
const startIndex = (currentPage - 1) * currentPageSize;
|
||||||
return filteredData.slice(startIndex, startIndex + pageSize);
|
return filteredData.slice(startIndex, startIndex + currentPageSize);
|
||||||
}, [filteredData, currentPage, pageSize, pagination]);
|
}, [filteredData, currentPage, currentPageSize, pagination]);
|
||||||
|
|
||||||
const totalPages = Math.ceil(filteredData.length / pageSize);
|
const totalPages = Math.ceil(filteredData.length / currentPageSize);
|
||||||
|
|
||||||
// Handle sorting
|
// Handle sorting
|
||||||
const handleSort = (key: string) => {
|
const handleSort = (key: string) => {
|
||||||
|
|
@ -257,6 +262,12 @@ export function FormGenerator<T extends Record<string, any>>({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle page size change
|
||||||
|
const handlePageSizeChange = (newPageSize: number) => {
|
||||||
|
setCurrentPageSize(newPageSize);
|
||||||
|
setCurrentPage(1); // Reset to first page when page size changes
|
||||||
|
};
|
||||||
|
|
||||||
// Handle column resizing
|
// Handle column resizing
|
||||||
const handleMouseDown = (e: React.MouseEvent, columnKey: string) => {
|
const handleMouseDown = (e: React.MouseEvent, columnKey: string) => {
|
||||||
if (!resizable) return;
|
if (!resizable) return;
|
||||||
|
|
@ -333,6 +344,7 @@ export function FormGenerator<T extends Record<string, any>>({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${styles.formGenerator} ${className}`}>
|
<div className={`${styles.formGenerator} ${className}`}>
|
||||||
|
{title && <h2 className={styles.title}>{title}</h2>}
|
||||||
|
|
||||||
|
|
||||||
{(searchable || filterable) && (
|
{(searchable || filterable) && (
|
||||||
|
|
@ -640,48 +652,68 @@ export function FormGenerator<T extends Record<string, any>>({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Pagination */}
|
{/* Pagination */}
|
||||||
{pagination && totalPages > 1 && (
|
{pagination && (
|
||||||
<div className={styles.pagination}>
|
<div className={styles.pagination}>
|
||||||
<button
|
{showPageSizeSelector && (
|
||||||
onClick={() => setCurrentPage(1)}
|
<div className={styles.pageSizeSelector}>
|
||||||
disabled={currentPage === 1}
|
<label htmlFor="pageSize">{t('formgen.pagination.pageSize', 'Items per page:')}</label>
|
||||||
className={styles.paginationButton}
|
<select
|
||||||
title={t('formgen.pagination.first')}
|
id="pageSize"
|
||||||
>
|
value={currentPageSize}
|
||||||
««
|
onChange={(e) => handlePageSizeChange(Number(e.target.value))}
|
||||||
</button>
|
className={styles.pageSizeSelect}
|
||||||
<button
|
>
|
||||||
onClick={() => setCurrentPage(currentPage - 1)}
|
{pageSizeOptions.map(size => (
|
||||||
disabled={currentPage === 1}
|
<option key={size} value={size}>{size}</option>
|
||||||
className={styles.paginationButton}
|
))}
|
||||||
title={t('formgen.pagination.prev')}
|
</select>
|
||||||
>
|
</div>
|
||||||
«
|
)}
|
||||||
</button>
|
|
||||||
|
|
||||||
<span className={styles.paginationInfo}>
|
{totalPages > 1 && (
|
||||||
{t('formgen.pagination.info')
|
<>
|
||||||
.replace('{page}', currentPage.toString())
|
<button
|
||||||
.replace('{total}', totalPages.toString())
|
onClick={() => setCurrentPage(1)}
|
||||||
.replace('{count}', filteredData.length.toString())}
|
disabled={currentPage === 1}
|
||||||
</span>
|
className={styles.paginationButton}
|
||||||
|
title={t('formgen.pagination.first')}
|
||||||
<button
|
>
|
||||||
onClick={() => setCurrentPage(currentPage + 1)}
|
««
|
||||||
disabled={currentPage === totalPages}
|
</button>
|
||||||
className={styles.paginationButton}
|
<button
|
||||||
title={t('formgen.pagination.next')}
|
onClick={() => setCurrentPage(currentPage - 1)}
|
||||||
>
|
disabled={currentPage === 1}
|
||||||
»
|
className={styles.paginationButton}
|
||||||
</button>
|
title={t('formgen.pagination.prev')}
|
||||||
<button
|
>
|
||||||
onClick={() => setCurrentPage(totalPages)}
|
«
|
||||||
disabled={currentPage === totalPages}
|
</button>
|
||||||
className={styles.paginationButton}
|
|
||||||
title={t('formgen.pagination.last')}
|
<span className={styles.paginationInfo}>
|
||||||
>
|
{t('formgen.pagination.info')
|
||||||
»»
|
.replace('{page}', currentPage.toString())
|
||||||
</button>
|
.replace('{total}', totalPages.toString())
|
||||||
|
.replace('{count}', filteredData.length.toString())}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(currentPage + 1)}
|
||||||
|
disabled={currentPage === totalPages}
|
||||||
|
className={styles.paginationButton}
|
||||||
|
title={t('formgen.pagination.next')}
|
||||||
|
>
|
||||||
|
»
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(totalPages)}
|
||||||
|
disabled={currentPage === totalPages}
|
||||||
|
className={styles.paginationButton}
|
||||||
|
title={t('formgen.pagination.last')}
|
||||||
|
>
|
||||||
|
»»
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -267,9 +267,13 @@ export default {
|
||||||
|
|
||||||
// File Table Columns
|
// File Table Columns
|
||||||
'files.column.name': 'Name',
|
'files.column.name': 'Name',
|
||||||
|
'files.column.filename': 'Dateiname',
|
||||||
'files.column.type': 'Typ',
|
'files.column.type': 'Typ',
|
||||||
|
'files.column.mimetype': 'MIME-Typ',
|
||||||
'files.column.size': 'Größe',
|
'files.column.size': 'Größe',
|
||||||
|
'files.column.filesize': 'Dateigröße',
|
||||||
'files.column.created': 'Erstellt',
|
'files.column.created': 'Erstellt',
|
||||||
|
'files.column.creationdate': 'Erstellungsdatum',
|
||||||
'files.column.source': 'Quelle',
|
'files.column.source': 'Quelle',
|
||||||
|
|
||||||
// File Types
|
// File Types
|
||||||
|
|
@ -334,6 +338,7 @@ export default {
|
||||||
'formgen.filter.placeholder': '{column} filtern',
|
'formgen.filter.placeholder': '{column} filtern',
|
||||||
'formgen.actions.column': 'Aktionen',
|
'formgen.actions.column': 'Aktionen',
|
||||||
'formgen.pagination.info': 'Seite {page} von {total} ({count} Einträge)',
|
'formgen.pagination.info': 'Seite {page} von {total} ({count} Einträge)',
|
||||||
|
'formgen.pagination.pageSize': 'Einträge pro Seite:',
|
||||||
'formgen.pagination.first': 'Erste Seite',
|
'formgen.pagination.first': 'Erste Seite',
|
||||||
'formgen.pagination.prev': 'Vorherige Seite',
|
'formgen.pagination.prev': 'Vorherige Seite',
|
||||||
'formgen.pagination.next': 'Nächste Seite',
|
'formgen.pagination.next': 'Nächste Seite',
|
||||||
|
|
|
||||||
|
|
@ -268,9 +268,13 @@ export default {
|
||||||
|
|
||||||
// File Table Columns
|
// File Table Columns
|
||||||
'files.column.name': 'Name',
|
'files.column.name': 'Name',
|
||||||
|
'files.column.filename': 'Filename',
|
||||||
'files.column.type': 'Type',
|
'files.column.type': 'Type',
|
||||||
|
'files.column.mimetype': 'MIME Type',
|
||||||
'files.column.size': 'Size',
|
'files.column.size': 'Size',
|
||||||
|
'files.column.filesize': 'File Size',
|
||||||
'files.column.created': 'Created',
|
'files.column.created': 'Created',
|
||||||
|
'files.column.creationdate': 'Creation Date',
|
||||||
'files.column.source': 'Source',
|
'files.column.source': 'Source',
|
||||||
|
|
||||||
// File Types
|
// File Types
|
||||||
|
|
@ -335,6 +339,7 @@ export default {
|
||||||
'formgen.filter.placeholder': 'Filter {column}',
|
'formgen.filter.placeholder': 'Filter {column}',
|
||||||
'formgen.actions.column': 'Actions',
|
'formgen.actions.column': 'Actions',
|
||||||
'formgen.pagination.info': 'Page {page} of {total} ({count} items)',
|
'formgen.pagination.info': 'Page {page} of {total} ({count} items)',
|
||||||
|
'formgen.pagination.pageSize': 'Items per page:',
|
||||||
'formgen.pagination.first': 'First page',
|
'formgen.pagination.first': 'First page',
|
||||||
'formgen.pagination.prev': 'Previous page',
|
'formgen.pagination.prev': 'Previous page',
|
||||||
'formgen.pagination.next': 'Next page',
|
'formgen.pagination.next': 'Next page',
|
||||||
|
|
|
||||||
|
|
@ -267,9 +267,13 @@ export default {
|
||||||
|
|
||||||
// File Table Columns
|
// File Table Columns
|
||||||
'files.column.name': 'Nom',
|
'files.column.name': 'Nom',
|
||||||
|
'files.column.filename': 'Nom de fichier',
|
||||||
'files.column.type': 'Type',
|
'files.column.type': 'Type',
|
||||||
|
'files.column.mimetype': 'Type MIME',
|
||||||
'files.column.size': 'Taille',
|
'files.column.size': 'Taille',
|
||||||
|
'files.column.filesize': 'Taille du fichier',
|
||||||
'files.column.created': 'Créé',
|
'files.column.created': 'Créé',
|
||||||
|
'files.column.creationdate': 'Date de création',
|
||||||
'files.column.source': 'Source',
|
'files.column.source': 'Source',
|
||||||
|
|
||||||
// File Types
|
// File Types
|
||||||
|
|
@ -334,6 +338,7 @@ export default {
|
||||||
'formgen.filter.placeholder': 'Filtrer {column}',
|
'formgen.filter.placeholder': 'Filtrer {column}',
|
||||||
'formgen.actions.column': 'Actions',
|
'formgen.actions.column': 'Actions',
|
||||||
'formgen.pagination.info': 'Page {page} sur {total} ({count} éléments)',
|
'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.first': 'Première page',
|
||||||
'formgen.pagination.prev': 'Page précédente',
|
'formgen.pagination.prev': 'Page précédente',
|
||||||
'formgen.pagination.next': 'Page suivante',
|
'formgen.pagination.next': 'Page suivante',
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ function Dashboard () {
|
||||||
const [isChatExpanded, setIsChatExpanded] = useState(false);
|
const [isChatExpanded, setIsChatExpanded] = useState(false);
|
||||||
const [selectedPrompt, setSelectedPrompt] = useState<Prompt | null>(null);
|
const [selectedPrompt, setSelectedPrompt] = useState<Prompt | null>(null);
|
||||||
const [isPromptAreaCollapsed, setIsPromptAreaCollapsed] = useState(false);
|
const [isPromptAreaCollapsed, setIsPromptAreaCollapsed] = useState(false);
|
||||||
|
const [currentWorkflowId, setCurrentWorkflowId] = useState<string | null>(null);
|
||||||
|
const [workflowCompleted, setWorkflowCompleted] = useState(false);
|
||||||
|
|
||||||
const handleChatToggleExpand = () => {
|
const handleChatToggleExpand = () => {
|
||||||
setIsChatExpanded(!isChatExpanded);
|
setIsChatExpanded(!isChatExpanded);
|
||||||
|
|
@ -25,7 +27,7 @@ function Dashboard () {
|
||||||
}
|
}
|
||||||
return workflowId;
|
return workflowId;
|
||||||
});
|
});
|
||||||
}, []);
|
}, [setCurrentWorkflowId, setWorkflowCompleted]);
|
||||||
|
|
||||||
const handleWorkflowCompletedChange = useCallback((completed: boolean) => {
|
const handleWorkflowCompletedChange = useCallback((completed: boolean) => {
|
||||||
setWorkflowCompleted(completed);
|
setWorkflowCompleted(completed);
|
||||||
|
|
@ -62,11 +64,3 @@ function Dashboard () {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default 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.');
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue