Build and Push Multi-Platform Images / build-and-push (push) Successful in 18s
- Replace div with semantic button elements in AppLayout for accessibility - Use Ant Design theme tokens instead of hardcoded colors in MailDetailPage - Add loading state to refresh buttons and pagination info - Add German empty state messages to tables - Clean up unnecessary ConfigProvider wrappers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
144 lines
4.3 KiB
TypeScript
144 lines
4.3 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { Table, Popover, Button, Space, message, Tooltip, Typography } from 'antd';
|
|
|
|
const { Title } = Typography;
|
|
import { ReloadOutlined } from '@ant-design/icons';
|
|
import dayjs from 'dayjs';
|
|
import { posteingangApi } from '../api/posteingang';
|
|
import type { PosteingangDocument } from '../api/posteingang';
|
|
import DocumentEditModal from '../components/DocumentEditModal';
|
|
import { getEnv } from '../utils/env';
|
|
import { AuthImage } from '../utils/auth-resource';
|
|
|
|
export default function ManuellBearbeitenPage() {
|
|
const [data, setData] = useState<PosteingangDocument[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [editModalOpen, setEditModalOpen] = useState(false);
|
|
const [selectedDoc, setSelectedDoc] = useState<PosteingangDocument | null>(null);
|
|
|
|
const fetchData = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const docs = await posteingangApi.getManuellList();
|
|
setData(docs || []);
|
|
} catch (e) {
|
|
message.error("Dokumente konnten nicht geladen werden.");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchData();
|
|
// Refresh interval every 30 seconds
|
|
const interval = setInterval(() => {
|
|
fetchData();
|
|
}, 30000);
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
|
|
const handleEdit = (doc: PosteingangDocument) => {
|
|
setSelectedDoc(doc);
|
|
setEditModalOpen(true);
|
|
};
|
|
|
|
const handleCloseModal = (openNext?: boolean) => {
|
|
setEditModalOpen(false);
|
|
if (openNext && data.length > 0) {
|
|
const currentIndex = data.findIndex(d => d.id === selectedDoc?.id);
|
|
const nextIndex = currentIndex !== -1 && currentIndex + 1 < data.length ? currentIndex + 1 : 0;
|
|
const nextDoc = data[nextIndex];
|
|
setTimeout(() => {
|
|
setSelectedDoc(nextDoc);
|
|
setEditModalOpen(true);
|
|
}, 300);
|
|
} else {
|
|
setSelectedDoc(null);
|
|
}
|
|
};
|
|
|
|
const popoverContent = (id: number) => (
|
|
<AuthImage
|
|
src={`${getEnv('VITE_API_URL')}/api/paperless/inbox/preview/${id}`}
|
|
width={400}
|
|
/>
|
|
);
|
|
|
|
const columns = [
|
|
{
|
|
title: 'Vorschau',
|
|
key: 'preview',
|
|
width: 150,
|
|
render: (_: any, record: PosteingangDocument) => (
|
|
<Popover content={popoverContent(record.id)} placement="right" trigger="hover">
|
|
<AuthImage
|
|
src={`${getEnv('VITE_API_URL')}/api/paperless/inbox/preview/${record.id}`}
|
|
width={100}
|
|
style={{ border: '1px solid #d9d9d9', objectFit: 'contain' }}
|
|
/>
|
|
</Popover>
|
|
),
|
|
},
|
|
{
|
|
title: 'Titel',
|
|
dataIndex: 'title',
|
|
key: 'title',
|
|
width: '35%',
|
|
},
|
|
{
|
|
title: 'Eingangsdatum',
|
|
key: 'eingangsdatum',
|
|
render: (_: any, record: PosteingangDocument) => {
|
|
return record.created ? dayjs(record.created).format('DD.MM.YYYY') : '-';
|
|
}
|
|
},
|
|
{
|
|
title: 'Importiert am',
|
|
dataIndex: 'added',
|
|
key: 'added',
|
|
render: (text: string) => dayjs(text).format('DD.MM.YYYY HH:mm'),
|
|
},
|
|
{
|
|
title: 'Aktionen',
|
|
key: 'action',
|
|
width: 150,
|
|
render: (_: any, record: PosteingangDocument) => (
|
|
<Button type="primary" onClick={() => handleEdit(record)}>
|
|
Bearbeiten
|
|
</Button>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
|
|
<Title level={3} style={{ margin: 0 }}>Manuell bearbeiten</Title>
|
|
<Space>
|
|
<Tooltip title="Manuell aktualisieren">
|
|
<Button icon={<ReloadOutlined />} onClick={fetchData} loading={loading} />
|
|
</Tooltip>
|
|
</Space>
|
|
</div>
|
|
<Table
|
|
columns={columns}
|
|
dataSource={data}
|
|
rowKey="id"
|
|
loading={loading}
|
|
pagination={{ pageSize: 20, showSizeChanger: true, showTotal: (t) => `${t} Dokumente` }}
|
|
locale={{ emptyText: 'Keine Einträge vorhanden' }}
|
|
/>
|
|
|
|
<DocumentEditModal
|
|
documentId={selectedDoc?.id || null}
|
|
document={selectedDoc}
|
|
open={editModalOpen}
|
|
onClose={handleCloseModal}
|
|
onSave={fetchData}
|
|
isPosteingang={false}
|
|
hasNextDocument={data.length > 1}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|