144 lines
4.2 KiB
TypeScript
144 lines
4.2 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { Table, Popover, Button, Space, message, ConfigProvider, Tooltip } from 'antd';
|
|
import { AuthImage } from '../utils/auth-resource';
|
|
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';
|
|
|
|
export default function PosteingangPage() {
|
|
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.getList();
|
|
setData(docs || []);
|
|
} catch (e) {
|
|
message.error("Posteingang konnte 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) => {
|
|
const cf = record.customFields?.find((f) => f.field === 9);
|
|
return cf?.value ? dayjs(cf.value).format('DD.MM.YYYY') : '-';
|
|
}
|
|
},
|
|
{
|
|
title: 'Importiert am',
|
|
dataIndex: 'added',
|
|
key: 'added',
|
|
render: (text: string) => dayjs(text).format('DD.MM.YYYY HH:mm'),
|
|
},
|
|
{
|
|
title: 'Aktion',
|
|
key: 'action',
|
|
width: 150,
|
|
render: (_: any, record: PosteingangDocument) => (
|
|
<Button type="primary" onClick={() => handleEdit(record)}>
|
|
Bearbeiten
|
|
</Button>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<ConfigProvider>
|
|
<div style={{ padding: '0 24px 24px' }}>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
|
|
<h2>Posteingang</h2>
|
|
<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 }}
|
|
/>
|
|
|
|
<DocumentEditModal
|
|
documentId={selectedDoc?.id || null}
|
|
document={selectedDoc}
|
|
open={editModalOpen}
|
|
onClose={handleCloseModal}
|
|
onSave={fetchData}
|
|
isPosteingang={true}
|
|
hasNextDocument={data.length > 1}
|
|
/>
|
|
</div>
|
|
</ConfigProvider>
|
|
);
|
|
}
|