feat: add functionality to manually split documents at specific pages via the UI and API
Build and Push Multi-Platform Images / build-and-push (push) Successful in 33s

This commit is contained in:
2026-05-05 17:51:53 +02:00
parent 810afa52cd
commit 13b07dfa71
5 changed files with 85 additions and 10 deletions
@@ -10,6 +10,7 @@ import {
QrcodeOutlined,
RedoOutlined,
RightOutlined,
ScissorOutlined,
ThunderboltOutlined,
UndoOutlined,
UserOutlined,
@@ -35,11 +36,12 @@ function buildDocuments(
pageCount: number,
splitPages: number[],
deletedPages: number[],
manualSplitPages: number[],
barcodes: InboxBarcode[],
): DocumentSegment[] {
if (pageCount === 0) return [];
const deleted = new Set(deletedPages);
const splits = new Set(splitPages.filter((p) => !deleted.has(p)));
const splits = new Set([...splitPages, ...manualSplitPages].filter((p) => !deleted.has(p)));
const docs: DocumentSegment[] = [];
let current: number[] = [];
@@ -570,7 +572,7 @@ export default function InboxDetailPage() {
const splitPages = file.barcodes
.filter((b) => b.splitBefore)
.map((b) => b.page);
return buildDocuments(file.pageCount, splitPages, file.deletedPages, file.barcodes);
return buildDocuments(file.pageCount, splitPages, file.deletedPages, file.manualSplitPages, file.barcodes);
}, [file]);
const effectivePages = useMemo<number[]>(() => {
@@ -700,6 +702,18 @@ export default function InboxDetailPage() {
};
const handleToggleSplit = async () => {
if (!file) return;
try {
await inboxApi.toggleSplit(file.id, selectedPage);
const list = await inboxApi.list();
const refreshed = list.find((f) => f.id === file.id) ?? null;
if (refreshed) setFile(refreshed);
} catch {
message.error('Trennung konnte nicht gespeichert werden');
}
};
const handleResetEdits = async () => {
if (!file) return;
try {
@@ -846,16 +860,16 @@ export default function InboxDetailPage() {
const canPrev = effectiveIndex > 0;
const canNext = effectiveIndex >= 0 && effectiveIndex < effectivePages.length - 1;
const canDelete = effectivePages.length > 1;
const isSplitPage = file.manualSplitPages.includes(selectedPage);
const canSplit = selectedPage !== currentDoc?.pages[0];
const rotationCount = Object.keys(file.rotations ?? {}).length;
const pendingEdits = file.deletedPages.length + rotationCount;
const manualSplitCount = file.manualSplitPages.length;
const pendingEdits = file.deletedPages.length + rotationCount + manualSplitCount;
const editsLabel = (() => {
const parts: string[] = [];
if (file.deletedPages.length > 0) {
parts.push(`${file.deletedPages.length} zur Löschung markiert`);
}
if (rotationCount > 0) {
parts.push(`${rotationCount} gedreht`);
}
if (file.deletedPages.length > 0) parts.push(`${file.deletedPages.length} zur Löschung markiert`);
if (rotationCount > 0) parts.push(`${rotationCount} gedreht`);
if (manualSplitCount > 0) parts.push(`${manualSplitCount} manuell getrennt`);
return parts.join(' · ');
})();
@@ -1211,6 +1225,18 @@ export default function InboxDetailPage() {
</Tooltip>
)}
<span style={{ width: 1, height: 20, background: 'rgba(255,255,255,0.2)' }} />
{canSplit && (
<Tooltip title={isSplitPage ? 'Manuelle Trennung aufheben' : 'Vor dieser Seite trennen'}>
<Button
type="text"
shape="circle"
icon={<ScissorOutlined style={{ fontSize: 16 }} />}
onClick={handleToggleSplit}
style={{ color: isSplitPage ? '#ffd666' : '#fff' }}
/>
</Tooltip>
)}
<span style={{ width: 1, height: 20, background: 'rgba(255,255,255,0.2)' }} />
<Tooltip title={scanMode ? 'Bereich-Scan abbrechen' : 'QR-Code in Bereich scannen'}>
<Button
type="text"