feat: 완전한 문서 관리 시스템 구현
✨ 주요 기능: - 문서 사라짐 문제 해결: API limit 제한으로 인한 문서 누락 해결 - 서적별 문서 관리: HTML과 PDF 통합 관리 시스템 - PDF 뷰어 개선: 인증, 네비게이션, 에러 처리 강화 - 서적 편집/삭제: 완전한 서적 관리 기능 🔧 기술적 개선: - /api/documents/all 엔드포인트 추가 (모든 문서 조회) - HTML/PDF 문서 타입별 아이콘 및 필터링 - 서적별 뷰에서 편집/삭제 버튼 추가 - PDF Manager와 서적 편집 페이지 연동 🎨 UI/UX 개선: - Devonthink 스타일 서적 그룹화 - HTML 문서 순서 관리와 PDF 관리 섹션 분리 - 문서 타입별 시각적 구분 (HTML: 파란색, PDF: 빨간색) - 2단계 확인을 통한 안전한 서적 삭제 �� 버그 수정: - PDF 삭제 시 undefined ID 전달 문제 해결 - 서적 편집 페이지 422 오류 해결 (URL 파라미터 문제) - PDF.js 워커 설정 및 인증 토큰 처리 개선
This commit is contained in:
@@ -95,16 +95,29 @@
|
||||
rows="3"
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- 서적 관리 버튼들 -->
|
||||
<div class="flex justify-between pt-4 border-t border-gray-200">
|
||||
<button @click="deleteBook()"
|
||||
class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors">
|
||||
<i class="fas fa-trash mr-2"></i>서적 삭제
|
||||
</button>
|
||||
|
||||
<button @click="saveBookInfo()"
|
||||
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
|
||||
<i class="fas fa-save mr-2"></i>서적 정보 저장
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 문서 순서 및 PDF 매칭 편집 -->
|
||||
<!-- HTML 문서 순서 및 PDF 매칭 편집 -->
|
||||
<div class="bg-white rounded-lg shadow-sm border">
|
||||
<div class="p-6 border-b border-gray-200">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<i class="fas fa-list-ol mr-2 text-green-600"></i>
|
||||
문서 순서 및 PDF 매칭
|
||||
<i class="fas fa-list-ol mr-2 text-blue-600"></i>
|
||||
HTML 문서 순서 및 PDF 매칭
|
||||
</h2>
|
||||
<div class="flex space-x-2">
|
||||
<button @click="autoSortByName()"
|
||||
@@ -138,15 +151,22 @@
|
||||
|
||||
<!-- 문서 정보 -->
|
||||
<div class="flex-1">
|
||||
<h3 class="font-medium text-gray-900" x-text="doc.title"></h3>
|
||||
<div class="flex items-center space-x-2">
|
||||
<!-- 문서 타입 아이콘 -->
|
||||
<i x-show="doc.html_path && !doc.pdf_path" class="fas fa-file-alt text-blue-500" title="HTML 문서"></i>
|
||||
<i x-show="doc.pdf_path && !doc.html_path" class="fas fa-file-pdf text-red-500" title="PDF 문서"></i>
|
||||
<i x-show="doc.html_path && doc.pdf_path" class="fas fa-file-archive text-purple-500" title="HTML + PDF"></i>
|
||||
|
||||
<h3 class="font-medium text-gray-900" x-text="doc.title"></h3>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500" x-text="doc.description || '설명 없음'"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PDF 매칭 및 컨트롤 -->
|
||||
<div class="flex items-center space-x-3">
|
||||
<!-- PDF 매칭 드롭다운 -->
|
||||
<div class="min-w-48 relative">
|
||||
<!-- PDF 매칭 드롭다운 (HTML 문서만) -->
|
||||
<div x-show="doc.html_path" class="min-w-48 relative">
|
||||
<select x-model="doc.matched_pdf_id"
|
||||
:class="doc.matched_pdf_id ? 'border-green-300 bg-green-50' : 'border-gray-300'"
|
||||
class="w-full px-3 py-2 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm">
|
||||
@@ -187,6 +207,67 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PDF 전용 문서 관리 -->
|
||||
<div class="bg-white rounded-lg shadow-sm border">
|
||||
<div class="p-6 border-b border-gray-200">
|
||||
<h2 class="text-lg font-semibold text-gray-900 flex items-center">
|
||||
<i class="fas fa-file-pdf mr-2 text-red-600"></i>
|
||||
등록된 PDF 문서 관리
|
||||
<span class="ml-2 px-2 py-1 bg-red-100 text-red-700 text-xs rounded-full" x-text="pdfDocuments.length + '개'"></span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="p-6">
|
||||
<!-- PDF 문서 목록 -->
|
||||
<div class="space-y-3">
|
||||
<template x-for="(pdf, index) in pdfDocuments" :key="pdf.id">
|
||||
<div class="bg-red-50 border border-red-200 rounded-lg p-4 hover:bg-red-100 transition-colors">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center flex-1">
|
||||
<!-- PDF 아이콘 -->
|
||||
<div class="w-10 h-10 bg-red-600 text-white rounded-full flex items-center justify-center text-sm font-medium mr-4">
|
||||
<i class="fas fa-file-pdf"></i>
|
||||
</div>
|
||||
|
||||
<!-- PDF 정보 -->
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center space-x-2">
|
||||
<h3 class="font-medium text-gray-900" x-text="pdf.title"></h3>
|
||||
<span class="px-2 py-1 bg-red-100 text-red-700 text-xs rounded-full">PDF 전용</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500" x-text="pdf.description || '설명 없음'"></p>
|
||||
<div class="flex items-center space-x-4 text-xs text-gray-400 mt-1">
|
||||
<span x-text="pdf.original_filename"></span>
|
||||
<span x-text="new Date(pdf.created_at).toLocaleDateString()"></span>
|
||||
<span x-show="pdf.file_size" x-text="Math.round(pdf.file_size / 1024) + 'KB'"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PDF 관리 버튼들 -->
|
||||
<div class="flex items-center space-x-2">
|
||||
<button @click="previewPDF(pdf)"
|
||||
class="px-3 py-1.5 bg-blue-100 text-blue-700 rounded-md hover:bg-blue-200 transition-colors text-sm">
|
||||
<i class="fas fa-eye mr-1"></i>미리보기
|
||||
</button>
|
||||
<button @click="deletePDF(pdf)"
|
||||
class="px-3 py-1.5 bg-red-100 text-red-700 rounded-md hover:bg-red-200 transition-colors text-sm">
|
||||
<i class="fas fa-trash mr-1"></i>삭제
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- 빈 상태 -->
|
||||
<div x-show="pdfDocuments.length === 0" class="text-center py-8">
|
||||
<i class="fas fa-file-pdf text-gray-400 text-3xl mb-4"></i>
|
||||
<p class="text-gray-500">등록된 PDF 문서가 없습니다</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -150,7 +150,10 @@
|
||||
<div class="p-6">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900 line-clamp-2" x-text="doc.title"></h3>
|
||||
<i class="fas fa-file-alt text-blue-500 text-xl"></i>
|
||||
<!-- 문서 타입별 아이콘 -->
|
||||
<i x-show="doc.html_path && !doc.pdf_path" class="fas fa-file-alt text-blue-500 text-xl" title="HTML 문서"></i>
|
||||
<i x-show="doc.pdf_path && !doc.html_path" class="fas fa-file-pdf text-red-500 text-xl" title="PDF 문서"></i>
|
||||
<i x-show="doc.html_path && doc.pdf_path" class="fas fa-file-archive text-purple-500 text-xl" title="HTML + PDF"></i>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-600 text-sm mb-3 line-clamp-3" x-text="doc.description || '설명 없음'"></p>
|
||||
@@ -222,11 +225,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 확장/축소 아이콘 -->
|
||||
<!-- 서적 관리 버튼들 -->
|
||||
<div class="flex items-center space-x-2">
|
||||
<button @click.stop="openBookDocuments(bookGroup.book)"
|
||||
class="px-3 py-1 text-xs bg-blue-100 text-blue-700 rounded-full hover:bg-blue-200 transition-colors">
|
||||
편집
|
||||
<!-- 서적 편집 버튼 -->
|
||||
<button x-show="bookGroup.book?.id"
|
||||
@click.stop="window.location.href = `/book-editor.html?id=${bookGroup.book.id}`"
|
||||
class="px-3 py-1 text-xs bg-blue-100 text-blue-700 rounded-md hover:bg-blue-200 transition-colors"
|
||||
title="서적 편집">
|
||||
<i class="fas fa-edit mr-1"></i>편집
|
||||
</button>
|
||||
|
||||
<!-- 서적 삭제 버튼 -->
|
||||
<button x-show="bookGroup.book?.id"
|
||||
@click.stop="deleteBook(bookGroup.book)"
|
||||
class="px-3 py-1 text-xs bg-red-100 text-red-700 rounded-md hover:bg-red-200 transition-colors"
|
||||
title="서적 삭제">
|
||||
<i class="fas fa-trash mr-1"></i>삭제
|
||||
</button>
|
||||
<i class="fas fa-chevron-down text-gray-400 transition-transform duration-200"
|
||||
:class="{'rotate-180': bookGroup.expanded}"></i>
|
||||
@@ -243,8 +257,17 @@
|
||||
<div class="flex items-center space-x-3 flex-1">
|
||||
<!-- 문서 타입 아이콘 -->
|
||||
<div class="w-8 h-8 rounded-md flex items-center justify-center"
|
||||
:class="doc.pdf_path ? 'bg-red-100 text-red-600' : 'bg-gray-100 text-gray-600'">
|
||||
<i :class="doc.pdf_path ? 'fas fa-file-pdf' : 'fas fa-file-alt'" class="text-xs"></i>
|
||||
:class="{
|
||||
'bg-blue-100 text-blue-600': doc.html_path && !doc.pdf_path,
|
||||
'bg-red-100 text-red-600': doc.pdf_path && !doc.html_path,
|
||||
'bg-purple-100 text-purple-600': doc.html_path && doc.pdf_path
|
||||
}">
|
||||
<i class="text-xs"
|
||||
:class="{
|
||||
'fas fa-file-alt': doc.html_path && !doc.pdf_path,
|
||||
'fas fa-file-pdf': doc.pdf_path && !doc.html_path,
|
||||
'fas fa-file-archive': doc.html_path && doc.pdf_path
|
||||
}"></i>
|
||||
</div>
|
||||
|
||||
<!-- 문서 정보 -->
|
||||
|
||||
@@ -279,8 +279,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 확장/축소 아이콘 -->
|
||||
<!-- 서적 관리 버튼들 -->
|
||||
<div class="flex items-center space-x-2">
|
||||
<!-- 서적 편집 버튼 -->
|
||||
<button x-show="bookGroup.book?.id"
|
||||
@click.stop="window.location.href = `/book-editor.html?id=${bookGroup.book.id}`"
|
||||
class="px-3 py-1 text-xs bg-blue-100 text-blue-700 rounded-md hover:bg-blue-200 transition-colors"
|
||||
title="서적 편집">
|
||||
<i class="fas fa-edit mr-1"></i>편집
|
||||
</button>
|
||||
|
||||
<span class="text-xs text-gray-500" x-text="bookGroup.pdfs.length + '개'"></span>
|
||||
<i class="fas fa-chevron-down text-gray-400 transition-transform duration-200"
|
||||
:class="{'rotate-180': bookGroup.expanded}"></i>
|
||||
@@ -319,7 +327,7 @@
|
||||
title="다운로드">
|
||||
<i class="fas fa-download text-xs"></i>
|
||||
</button>
|
||||
<button @click.stop="deletePDF(pdf.id)"
|
||||
<button @click.stop="deletePDF(pdf)"
|
||||
class="p-2 text-gray-400 hover:text-red-600 transition-colors rounded-md hover:bg-red-50"
|
||||
title="삭제">
|
||||
<i class="fas fa-trash text-xs"></i>
|
||||
|
||||
@@ -213,6 +213,11 @@ class DocumentServerAPI {
|
||||
return await this.get('/documents/', params);
|
||||
}
|
||||
|
||||
async getAllDocuments() {
|
||||
// 모든 문서를 가져오는 전용 엔드포인트
|
||||
return await this.get('/documents/all');
|
||||
}
|
||||
|
||||
async getDocumentsHierarchy() {
|
||||
return await this.get('/documents/hierarchy/structured');
|
||||
}
|
||||
@@ -429,6 +434,14 @@ class DocumentServerAPI {
|
||||
return await this.post('/books', bookData);
|
||||
}
|
||||
|
||||
async updateBook(bookId, bookData) {
|
||||
return await this.put(`/books/${bookId}`, bookData);
|
||||
}
|
||||
|
||||
async deleteBook(bookId) {
|
||||
return await this.delete(`/books/${bookId}`);
|
||||
}
|
||||
|
||||
async getBook(bookId) {
|
||||
return await this.get(`/books/${bookId}`);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ window.bookDocumentsApp = () => ({
|
||||
|
||||
try {
|
||||
// 모든 문서 가져오기
|
||||
const allDocuments = await window.api.getDocuments();
|
||||
const allDocuments = await window.api.getAllDocuments();
|
||||
|
||||
if (this.bookId === 'none') {
|
||||
// 서적 미분류 HTML 문서들만 (폴더로 구분)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// 서적 편집 애플리케이션 컴포넌트
|
||||
window.bookEditorApp = () => ({
|
||||
// 상태 관리
|
||||
documents: [],
|
||||
documents: [], // HTML 문서들 (순서 관리용)
|
||||
pdfDocuments: [], // PDF 전용 문서들 (별도 관리용)
|
||||
bookInfo: {},
|
||||
availablePDFs: [],
|
||||
loading: false,
|
||||
@@ -40,8 +41,9 @@ window.bookEditorApp = () => ({
|
||||
// URL 파라미터 파싱
|
||||
parseUrlParams() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
this.bookId = urlParams.get('bookId');
|
||||
this.bookId = urlParams.get('id') || urlParams.get('bookId'); // 'id' 또는 'bookId' 파라미터 지원
|
||||
console.log('📖 편집할 서적 ID:', this.bookId);
|
||||
console.log('📖 URL 파라미터들:', Object.fromEntries(urlParams));
|
||||
},
|
||||
|
||||
// 인증 상태 확인
|
||||
@@ -74,21 +76,35 @@ window.bookEditorApp = () => ({
|
||||
this.error = '';
|
||||
|
||||
try {
|
||||
console.log('🔍 서적 ID 확인:', this.bookId);
|
||||
|
||||
// 서적 정보 로드
|
||||
this.bookInfo = await window.api.getBook(this.bookId);
|
||||
console.log('📚 서적 정보 로드:', this.bookInfo);
|
||||
|
||||
// 모든 문서 가져와서 이 서적에 속한 HTML 문서들만 필터링 (폴더로 구분)
|
||||
const allDocuments = await window.api.getDocuments();
|
||||
// 모든 문서 가져와서 이 서적에 속한 문서들 필터링
|
||||
const allDocuments = await window.api.getAllDocuments();
|
||||
|
||||
// HTML 문서만 (순서 관리용)
|
||||
this.documents = allDocuments
|
||||
.filter(doc =>
|
||||
doc.book_id === this.bookId &&
|
||||
doc.html_path &&
|
||||
doc.html_path.includes('/documents/') // HTML은 documents 폴더에 저장됨
|
||||
doc.html_path &&
|
||||
doc.html_path.includes('/documents/')
|
||||
)
|
||||
.sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0)); // 순서대로 정렬
|
||||
|
||||
console.log('📄 서적 문서들:', this.documents.length, '개');
|
||||
// PDF 전용 문서들 (별도 관리용)
|
||||
this.pdfDocuments = allDocuments
|
||||
.filter(doc =>
|
||||
doc.book_id === this.bookId &&
|
||||
doc.pdf_path &&
|
||||
!doc.html_path // PDF만 있는 문서
|
||||
)
|
||||
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); // 최신순
|
||||
|
||||
console.log('📄 HTML 문서들:', this.documents.length, '개 (순서 관리)');
|
||||
console.log('📕 PDF 전용 문서들:', this.pdfDocuments.length, '개 (별도 관리)');
|
||||
|
||||
// 각 문서의 PDF 매칭 상태 확인
|
||||
this.documents.forEach((doc, index) => {
|
||||
@@ -295,6 +311,93 @@ window.bookEditorApp = () => ({
|
||||
}
|
||||
},
|
||||
|
||||
// 서적 정보 저장
|
||||
async saveBookInfo() {
|
||||
try {
|
||||
await window.api.updateBook(this.bookId, {
|
||||
title: this.bookInfo.title,
|
||||
author: this.bookInfo.author,
|
||||
description: this.bookInfo.description
|
||||
});
|
||||
|
||||
this.showNotification('서적 정보가 저장되었습니다', 'success');
|
||||
} catch (error) {
|
||||
console.error('서적 정보 저장 실패:', error);
|
||||
this.showNotification('서적 정보 저장에 실패했습니다: ' + error.message, 'error');
|
||||
}
|
||||
},
|
||||
|
||||
// 서적 삭제 (모든 문서 포함)
|
||||
async deleteBook() {
|
||||
if (!this.bookInfo.title) {
|
||||
alert('서적 정보가 로드되지 않았습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmMessage = `"${this.bookInfo.title}" 서적을 완전히 삭제하시겠습니까?\n\n⚠️ 경고: 이 작업은 되돌릴 수 없습니다!\n\n삭제될 항목:\n- 서적 정보\n- HTML 문서 ${this.documents.length}개\n- PDF 전용 문서 ${this.pdfDocuments.length}개\n- 관련된 모든 하이라이트, 노트, 링크`;
|
||||
|
||||
if (!confirm(confirmMessage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 한 번 더 확인
|
||||
const finalConfirm = prompt(`정말로 삭제하시려면 서적 제목을 입력하세요:\n"${this.bookInfo.title}"`);
|
||||
if (finalConfirm !== this.bookInfo.title) {
|
||||
alert('서적 제목이 일치하지 않습니다. 삭제가 취소되었습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 서적에 속한 모든 HTML 문서 삭제
|
||||
for (const doc of this.documents) {
|
||||
console.log(`🗑️ HTML 문서 삭제 중: ${doc.title}`);
|
||||
await window.api.deleteDocument(doc.id);
|
||||
}
|
||||
|
||||
// 서적에 속한 모든 PDF 전용 문서 삭제
|
||||
for (const doc of this.pdfDocuments) {
|
||||
console.log(`🗑️ PDF 문서 삭제 중: ${doc.title}`);
|
||||
await window.api.deleteDocument(doc.id);
|
||||
}
|
||||
|
||||
// 서적 삭제
|
||||
await window.api.deleteBook(this.bookId);
|
||||
|
||||
alert('서적이 완전히 삭제되었습니다.');
|
||||
|
||||
// 메인 페이지로 이동
|
||||
window.location.href = '/index.html';
|
||||
} catch (error) {
|
||||
console.error('서적 삭제 실패:', error);
|
||||
alert('서적 삭제에 실패했습니다: ' + error.message);
|
||||
}
|
||||
},
|
||||
|
||||
// PDF 미리보기
|
||||
previewPDF(pdf) {
|
||||
// PDF 뷰어 페이지로 이동
|
||||
window.open(`/viewer.html?id=${pdf.id}`, '_blank');
|
||||
},
|
||||
|
||||
// PDF 삭제
|
||||
async deletePDF(pdf) {
|
||||
if (!confirm(`"${pdf.title}" PDF 문서를 삭제하시겠습니까?\n\n이 작업은 되돌릴 수 없습니다.`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await window.api.deleteDocument(pdf.id);
|
||||
|
||||
// PDF 목록에서 제거
|
||||
this.pdfDocuments = this.pdfDocuments.filter(p => p.id !== pdf.id);
|
||||
|
||||
this.showNotification('PDF 문서가 삭제되었습니다', 'success');
|
||||
} catch (error) {
|
||||
console.error('PDF 삭제 실패:', error);
|
||||
this.showNotification('PDF 삭제에 실패했습니다: ' + error.message, 'error');
|
||||
}
|
||||
},
|
||||
|
||||
// 뒤로가기
|
||||
goBack() {
|
||||
window.location.href = `book-documents.html?bookId=${this.bookId}`;
|
||||
|
||||
@@ -134,7 +134,10 @@ window.documentApp = () => ({
|
||||
this.error = '';
|
||||
|
||||
try {
|
||||
const allDocuments = await window.api.getDocuments();
|
||||
const allDocuments = await window.api.getAllDocuments();
|
||||
|
||||
// 디버깅: API 응답 원본 확인
|
||||
console.log('🔍 API 응답 원본 (첫 3개):', JSON.stringify(allDocuments.slice(0, 3), null, 2));
|
||||
|
||||
// HTML 문서만 필터링 (PDF 파일 제외)
|
||||
this.documents = allDocuments.filter(doc =>
|
||||
@@ -146,6 +149,19 @@ window.documentApp = () => ({
|
||||
console.log('📄 HTML 문서:', this.documents.length, '개');
|
||||
console.log('📄 PDF 파일:', allDocuments.length - this.documents.length, '개 (제외됨)');
|
||||
|
||||
// 디버깅: 사라진 문서 찾기
|
||||
console.log('🔍 HTML 경로가 있는 문서들:');
|
||||
allDocuments.forEach(doc => {
|
||||
if (doc.html_path) {
|
||||
console.log(` - ${doc.title}: ${doc.html_path}`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('🔍 필터링된 문서들:');
|
||||
this.documents.forEach(doc => {
|
||||
console.log(` - ${doc.title}: ${doc.html_path}`);
|
||||
});
|
||||
|
||||
this.updateAvailableTags();
|
||||
this.filterDocuments();
|
||||
this.syncUIState(); // UI 상태 동기화
|
||||
@@ -206,6 +222,32 @@ window.documentApp = () => ({
|
||||
this.filterDocuments();
|
||||
},
|
||||
|
||||
// 서적 삭제
|
||||
async deleteBook(book) {
|
||||
if (!book || !book.id) {
|
||||
alert('서적 정보가 올바르지 않습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmMessage = `"${book.title}" 서적을 삭제하시겠습니까?\n\n⚠️ 주의: 이 서적에 속한 모든 문서들이 '서적 미분류'로 이동됩니다.`;
|
||||
|
||||
if (!confirm(confirmMessage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await window.api.deleteBook(book.id);
|
||||
|
||||
// 문서 목록 다시 로드
|
||||
await this.loadDocuments();
|
||||
|
||||
alert('서적이 삭제되었습니다.');
|
||||
} catch (error) {
|
||||
console.error('서적 삭제 실패:', error);
|
||||
alert('서적 삭제에 실패했습니다: ' + error.message);
|
||||
}
|
||||
},
|
||||
|
||||
// 필터 초기화
|
||||
clearFilters() {
|
||||
this.searchQuery = '';
|
||||
|
||||
@@ -67,7 +67,7 @@ window.pdfManagerApp = () => ({
|
||||
|
||||
try {
|
||||
// 모든 문서 가져오기
|
||||
this.allDocuments = await window.api.getDocuments();
|
||||
this.allDocuments = await window.api.getAllDocuments();
|
||||
|
||||
// PDF 파일들만 필터링
|
||||
this.pdfDocuments = this.allDocuments.filter(doc =>
|
||||
|
||||
Reference in New Issue
Block a user