feat(library): 자료실 드래그 업로드 + 오버레이
자료실 페이지에서 드래그 앤 드롭 업로드 지원. 업로드 후 자료실 내에서 트리+목록 새로고침 (문서 페이지로 이동하지 않음). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -152,13 +152,43 @@
|
||||
window.open(`/api/documents/${doc.id}/preview?token=${getAccessToken()}&download=true`);
|
||||
}
|
||||
|
||||
// ─── 업로드 ───
|
||||
// ─── 업로드 (버튼 + 드래그) ───
|
||||
|
||||
const MAX_UPLOAD_BYTES = 100 * 1024 * 1024;
|
||||
let fileInput;
|
||||
let uploadingCount = $state(0);
|
||||
let dragging = $state(false);
|
||||
let dragCounter = 0;
|
||||
|
||||
async function handleUpload(e) {
|
||||
const files = Array.from(e.target.files || []);
|
||||
onMount(() => {
|
||||
function onDragEnter(e) { e.preventDefault(); dragCounter++; dragging = true; }
|
||||
function onDragOver(e) { e.preventDefault(); }
|
||||
function onDragLeave(e) { e.preventDefault(); dragCounter--; if (dragCounter <= 0) { dragging = false; dragCounter = 0; } }
|
||||
function onDrop(e) { e.preventDefault(); dragging = false; dragCounter = 0; uploadFiles(e.dataTransfer?.files); }
|
||||
window.addEventListener('dragenter', onDragEnter);
|
||||
window.addEventListener('dragover', onDragOver);
|
||||
window.addEventListener('dragleave', onDragLeave);
|
||||
window.addEventListener('drop', onDrop);
|
||||
return () => {
|
||||
window.removeEventListener('dragenter', onDragEnter);
|
||||
window.removeEventListener('dragover', onDragOver);
|
||||
window.removeEventListener('dragleave', onDragLeave);
|
||||
window.removeEventListener('drop', onDrop);
|
||||
};
|
||||
});
|
||||
|
||||
function handleUpload(e) {
|
||||
uploadFiles(e.target.files);
|
||||
fileInput.value = '';
|
||||
}
|
||||
|
||||
async function uploadFiles(fileList) {
|
||||
const allFiles = Array.from(fileList || []);
|
||||
const files = allFiles.filter(f => f.size <= MAX_UPLOAD_BYTES);
|
||||
const tooLarge = allFiles.filter(f => f.size > MAX_UPLOAD_BYTES);
|
||||
if (tooLarge.length > 0) {
|
||||
addToast('error', `100MB 초과 파일 ${tooLarge.length}건 제외됨`);
|
||||
}
|
||||
if (files.length === 0) return;
|
||||
|
||||
uploadingCount = files.length;
|
||||
@@ -178,7 +208,6 @@
|
||||
}
|
||||
|
||||
uploadingCount = 0;
|
||||
fileInput.value = '';
|
||||
|
||||
if (success > 0) {
|
||||
addToast('success', `${success}건 업로드 완료`);
|
||||
@@ -460,3 +489,16 @@
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 드래그 업로드 오버레이 -->
|
||||
{#if dragging}
|
||||
<div class="fixed inset-0 z-50 bg-accent/10 border-2 border-dashed border-accent flex items-center justify-center">
|
||||
<div class="bg-surface rounded-xl px-8 py-6 shadow-xl text-center">
|
||||
<Upload size={32} class="mx-auto mb-2 text-accent" />
|
||||
<p class="text-sm font-medium text-accent">자료실에 파일 업로드</p>
|
||||
{#if activePath}
|
||||
<p class="text-xs text-dim mt-1">경로: {activePath}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user