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
Build and Push Multi-Platform Images / build-and-push (push) Successful in 33s
This commit is contained in:
@@ -19,6 +19,7 @@ export interface InboxFile {
|
||||
source: InboxSource;
|
||||
pageCount: number;
|
||||
deletedPages: number[];
|
||||
manualSplitPages: number[];
|
||||
rotations: Record<string, number>;
|
||||
barcodes: InboxBarcode[];
|
||||
createdAt: string;
|
||||
@@ -62,6 +63,9 @@ export const inboxApi = {
|
||||
remove: (id: string) =>
|
||||
api.delete(`/api/inbox/${encodeURIComponent(id)}`).then((r) => r.data),
|
||||
|
||||
toggleSplit: (id: string, page: number) =>
|
||||
api.post(`/api/inbox/${encodeURIComponent(id)}/pages/${page}/split`).then(() => {}),
|
||||
|
||||
removePage: (id: string, page: number) =>
|
||||
api
|
||||
.delete(`/api/inbox/${encodeURIComponent(id)}/pages/${page}`)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user