Fix: 노트 링크 관련 모든 기능 완전 수정
주요 수정사항:
- 노트 간 링크 네비게이션 수정 (target_note_id 우선 사용)
- 노트 백링크 네비게이션 수정 (source_note_id 우선 사용)
- 노트 링크 삭제 API 분기 처리 (/note-links vs /document-links)
- 하이라이트 삭제 시 메모 캐시 무효화 추가
- 하이라이트 메모 삭제 API 엔드포인트 추가 (DELETE /highlight-notes/{note_id})
- URL 파싱 개선 (null/undefined ID 감지 및 오류 처리)
- 노트 링크 생성 응답에 source_content_type, target_content_type 추가
- 통합 툴팁에서 노트 링크 제목 표시 수정 (target_note_title 사용)
- 링크 삭제 버튼에서 null 참조 오류 수정
수정된 파일:
- frontend: viewer-core.js, link-manager.js, highlight-manager.js, api.js, cached-api.js
- backend: note_links.py, notes.py
- 브라우저 캐시 무효화: 버전 v=2025012623
This commit is contained in:
@@ -246,19 +246,24 @@ window.documentViewer = () => ({
|
||||
// ==================== URL 파라미터 처리 ====================
|
||||
parseUrlParameters() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
this.documentId = urlParams.get('id');
|
||||
const rawId = urlParams.get('id');
|
||||
|
||||
// null 문자열이나 빈 값 처리
|
||||
if (!rawId || rawId === 'null' || rawId === 'undefined' || rawId.trim() === '') {
|
||||
console.error('❌ 유효하지 않은 문서 ID:', rawId);
|
||||
throw new Error('유효한 문서 ID가 필요합니다. URL을 확인해주세요.');
|
||||
}
|
||||
|
||||
this.documentId = rawId;
|
||||
// contentType 파라미터를 올바르게 가져오기 (type과 contentType 둘 다 지원)
|
||||
this.contentType = urlParams.get('contentType') || urlParams.get('type') || 'document';
|
||||
|
||||
console.log('🔍 URL 파싱 결과:', {
|
||||
rawId: rawId,
|
||||
documentId: this.documentId,
|
||||
contentType: this.contentType,
|
||||
fullURL: window.location.href
|
||||
});
|
||||
|
||||
if (!this.documentId) {
|
||||
throw new Error('문서 ID가 필요합니다.');
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 문서 로드 ====================
|
||||
@@ -1162,7 +1167,8 @@ window.documentViewer = () => ({
|
||||
const link = this.linkManager.documentLinks.find(l => l.id === linkId);
|
||||
if (link && !overlappingLinks.find(l => l.id === link.id)) {
|
||||
overlappingLinks.push(link);
|
||||
console.log('✅ 겹치는 링크 발견:', link.target_document_title);
|
||||
const linkTitle = link.target_note_title || link.target_document_title || 'Unknown';
|
||||
console.log('✅ 겹치는 링크 발견:', linkTitle);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1362,7 +1368,7 @@ window.documentViewer = () => ({
|
||||
'<path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clip-rule="evenodd"/>'
|
||||
}
|
||||
</svg>
|
||||
<span class="font-medium ${iconClass}">${link.target_document_title}</span>
|
||||
<span class="font-medium ${iconClass}">${link.target_note_title || link.target_document_title}</span>
|
||||
</div>
|
||||
|
||||
${link.target_text ? `
|
||||
@@ -1390,7 +1396,7 @@ window.documentViewer = () => ({
|
||||
</div>
|
||||
|
||||
<!-- 삭제 버튼 -->
|
||||
<button onclick="event.stopPropagation(); window.documentViewerInstance.deleteLinkWithConfirm('${link.id}', '${link.target_document_title.replace(/'/g, "\\'")}');"
|
||||
<button onclick="event.stopPropagation(); window.documentViewerInstance.deleteLinkWithConfirm('${link.id}', '${(link.target_note_title || link.target_document_title).replace(/'/g, "\\'")}');"
|
||||
class="ml-3 p-1 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded transition-colors duration-200 opacity-0 group-hover:opacity-100"
|
||||
title="링크 삭제">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
@@ -1650,17 +1656,21 @@ window.documentViewer = () => ({
|
||||
console.log('🔙 백링크 클릭:', backlink);
|
||||
console.log('📋 백링크 상세 정보:', {
|
||||
source_document_id: backlink.source_document_id,
|
||||
source_note_id: backlink.source_note_id,
|
||||
source_content_type: backlink.source_content_type,
|
||||
source_document_title: backlink.source_document_title
|
||||
});
|
||||
|
||||
if (!backlink.source_document_id) {
|
||||
console.error('❌ 소스 문서 ID가 없습니다!', backlink);
|
||||
// 소스 ID 찾기 (노트 백링크의 경우 source_note_id 우선)
|
||||
const sourceId = backlink.source_note_id || backlink.source_document_id;
|
||||
if (!sourceId) {
|
||||
console.error('❌ 소스 문서/노트 ID가 없습니다!', backlink);
|
||||
alert('백링크 소스를 찾을 수 없습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
return this.linkManager.navigateToSourceDocument(backlink.source_document_id, backlink);
|
||||
console.log('✅ 백링크 소스 ID 발견:', sourceId);
|
||||
return this.linkManager.navigateToSourceDocument(sourceId, backlink);
|
||||
},
|
||||
|
||||
// 링크 삭제 (확인 후)
|
||||
@@ -1676,8 +1686,16 @@ window.documentViewer = () => ({
|
||||
try {
|
||||
console.log('🗑️ 링크 삭제 시작:', linkId);
|
||||
|
||||
// API 호출
|
||||
await this.api.deleteDocumentLink(linkId);
|
||||
// 출발지 타입에 따라 다른 API 사용
|
||||
if (this.contentType === 'note') {
|
||||
// 노트에서 출발하는 링크: NoteLink API 사용
|
||||
console.log('📝 노트 링크 삭제 API 호출');
|
||||
await this.api.delete(`/note-links/${linkId}`);
|
||||
} else {
|
||||
// 문서에서 출발하는 링크: DocumentLink API 사용
|
||||
console.log('📄 문서 링크 삭제 API 호출');
|
||||
await this.api.deleteDocumentLink(linkId);
|
||||
}
|
||||
console.log('✅ 링크 삭제 성공');
|
||||
|
||||
// 툴팁 숨기기
|
||||
|
||||
Reference in New Issue
Block a user