subdocument-splitting-plan
This commit is contained in:
1 parent
f09384d2e6
commit
ca06ca2050
47 files changed
+4097
-136
No files matched your search
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import AttachmentMenu, { type AttachmentMoveTarget } from '$lib/components/AttachmentMenu.svelte';
|
||||
import AttachmentPreview from '$lib/components/AttachmentPreview.svelte';
|
||||
import Button from '$lib/components/ui/button.svelte';
|
||||
import type { AttachmentLocation, SubDocument, ZipAttachment } from '$lib/zip-processing';
|
||||
@@ -10,6 +11,15 @@
|
||||
thumbnailWidth: number;
|
||||
isBlockDragSource?: boolean;
|
||||
isBlockDropTarget?: boolean;
|
||||
groupingMode?: boolean;
|
||||
selectedPaths?: Set<string>;
|
||||
onToggleSelection?: (path: string) => void;
|
||||
autoFocusName?: boolean;
|
||||
moveTargets?: AttachmentMoveTarget[];
|
||||
onMoveToTarget?: (path: string, targetId: string) => void;
|
||||
onMoveToLoose?: (path: string) => void;
|
||||
onSplit?: (attachment: ZipAttachment) => void;
|
||||
onRemoveAttachment?: (attachment: ZipAttachment) => void;
|
||||
onSubDocumentChange?: (next: SubDocument) => void;
|
||||
onRemove?: () => void;
|
||||
onAttachmentMove?: (source: AttachmentLocation, target: AttachmentLocation) => void;
|
||||
@@ -28,6 +38,15 @@
|
||||
thumbnailWidth = 200,
|
||||
isBlockDragSource = false,
|
||||
isBlockDropTarget = false,
|
||||
groupingMode = false,
|
||||
selectedPaths = new Set<string>(),
|
||||
onToggleSelection = () => {},
|
||||
autoFocusName = false,
|
||||
moveTargets = [],
|
||||
onMoveToTarget = () => {},
|
||||
onMoveToLoose = () => {},
|
||||
onSplit = () => {},
|
||||
onRemoveAttachment = () => {},
|
||||
onSubDocumentChange = () => {},
|
||||
onRemove = () => {},
|
||||
onAttachmentMove = () => {},
|
||||
@@ -40,6 +59,7 @@
|
||||
downloadDisabled = false
|
||||
}: Props = $props();
|
||||
|
||||
let nameInput = $state<HTMLInputElement | null>(null);
|
||||
let subDocumentName = $state('');
|
||||
let dragIndex = $state<number | null>(null);
|
||||
let dropIndex = $state<number | null>(null);
|
||||
@@ -48,6 +68,14 @@
|
||||
subDocumentName = subDocument.name;
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (autoFocusName && nameInput) {
|
||||
nameInput.focus();
|
||||
nameInput.select();
|
||||
nameInput.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
||||
}
|
||||
});
|
||||
|
||||
const emitChange = (overrides: Partial<SubDocument> = {}) => {
|
||||
onSubDocumentChange({
|
||||
...subDocument,
|
||||
@@ -81,6 +109,11 @@
|
||||
};
|
||||
|
||||
const handleCardDragStart = (index: number, event: DragEvent) => {
|
||||
if (groupingMode) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
dragIndex = index;
|
||||
dropIndex = index;
|
||||
|
||||
@@ -195,6 +228,7 @@
|
||||
<label class="block min-w-0 flex-1">
|
||||
<span class="sr-only">Teildokumentname</span>
|
||||
<input
|
||||
bind:this={nameInput}
|
||||
class="w-full max-w-md rounded-md border border-primary-200 bg-white px-3 py-1.5 text-[15px] font-semibold text-primary-900 outline-none transition focus:border-primary-400 focus:ring-2 focus:ring-primary-200"
|
||||
type="text"
|
||||
value={subDocumentName}
|
||||
@@ -272,33 +306,70 @@
|
||||
dropIndex === index
|
||||
? 'border-primary-400 ring-1 ring-primary-200'
|
||||
: 'border-primary-100',
|
||||
dragIndex === index ? 'opacity-60' : ''
|
||||
dragIndex === index ? 'opacity-60' : '',
|
||||
groupingMode && selectedPaths.has(attachment.path)
|
||||
? 'border-primary-500 ring-2 ring-primary-300'
|
||||
: ''
|
||||
)}
|
||||
style={`width: ${thumbnailWidth}px;`}
|
||||
draggable="true"
|
||||
draggable={groupingMode ? 'false' : 'true'}
|
||||
ondragstart={(event) => handleCardDragStart(index, event)}
|
||||
ondragover={(event) => handleCardDragOver(index, event)}
|
||||
ondrop={(event) => handleCardDrop(index, event)}
|
||||
ondragend={handleCardDragEnd}
|
||||
>
|
||||
<div class="flex min-w-0 flex-1 flex-row items-baseline gap-2 py-1">
|
||||
<button
|
||||
class="w-fit cursor-grab rounded-md border border-primary-200 bg-white px-2 py-1 text-sm font-semibold leading-none text-primary-700 active:cursor-grabbing"
|
||||
draggable="false"
|
||||
type="button"
|
||||
aria-label="Datei verschieben"
|
||||
>
|
||||
::
|
||||
</button>
|
||||
{#if groupingMode}
|
||||
<label class="flex cursor-pointer flex-col gap-2">
|
||||
<div class="flex items-center gap-2 px-1 text-[13px] font-medium text-primary-900">
|
||||
<input
|
||||
class="h-4 w-4 accent-primary-700"
|
||||
type="checkbox"
|
||||
checked={selectedPaths.has(attachment.path)}
|
||||
onchange={() => onToggleSelection(attachment.path)}
|
||||
/>
|
||||
<span class="truncate"
|
||||
>{selectedPaths.has(attachment.path) ? 'Ausgewählt' : 'Auswählen'}</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="truncate text-[13px] font-medium leading-tight text-primary-900"
|
||||
title={attachment.name}
|
||||
>
|
||||
{attachment.name}
|
||||
<div
|
||||
class="truncate text-[13px] font-medium leading-tight text-primary-900"
|
||||
title={attachment.name}
|
||||
>
|
||||
{attachment.name}
|
||||
</div>
|
||||
<AttachmentPreview {attachment} />
|
||||
</label>
|
||||
{:else}
|
||||
<div class="flex min-w-0 flex-1 flex-row items-center gap-1 py-1">
|
||||
<button
|
||||
class="w-fit cursor-grab rounded-md border border-primary-200 bg-white px-2 py-1 text-sm font-semibold leading-none text-primary-700 active:cursor-grabbing"
|
||||
draggable="false"
|
||||
type="button"
|
||||
aria-label="Datei verschieben"
|
||||
>
|
||||
::
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="min-w-0 flex-1 truncate text-[13px] font-medium leading-tight text-primary-900"
|
||||
title={attachment.name}
|
||||
>
|
||||
{attachment.name}
|
||||
</div>
|
||||
|
||||
<AttachmentMenu
|
||||
{attachment}
|
||||
{moveTargets}
|
||||
canSplit={attachment.kind === 'pdf'}
|
||||
onMoveToTarget={(targetId) => onMoveToTarget(attachment.path, targetId)}
|
||||
onMoveToLoose={() => onMoveToLoose(attachment.path)}
|
||||
onSplit={() => onSplit(attachment)}
|
||||
onRemove={() => onRemoveAttachment(attachment)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<AttachmentPreview {attachment} />
|
||||
<AttachmentPreview {attachment} />
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
Reference in new issue
Block a user