diff --git a/frontend/static/js/viewer/features/link-manager.js b/frontend/static/js/viewer/features/link-manager.js index b6c2036..67ea192 100644 --- a/frontend/static/js/viewer/features/link-manager.js +++ b/frontend/static/js/viewer/features/link-manager.js @@ -494,39 +494,77 @@ class LinkManager { const tooltip = document.createElement('div'); tooltip.id = 'link-tooltip'; - tooltip.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-4 z-50 max-w-lg'; - tooltip.style.minWidth = '350px'; + tooltip.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-5 z-50 max-w-2xl'; + tooltip.style.minWidth = '450px'; + tooltip.style.maxHeight = '80vh'; + tooltip.style.overflowY = 'auto'; + + // 생성 날짜 포맷팅 + const createdDate = link.created_at ? this.formatDate(link.created_at) : '알 수 없음'; const tooltipHTML = `
-
링크 정보
-
- "${link.selected_text}" +
+
+ + + + 링크 정보 +
+
${createdDate}
+
+ +
+
선택된 텍스트
+
"${link.selected_text}"
-
-
연결된 문서
-
-
${link.target_document_title}
- ${link.target_text ? `
대상 텍스트: "${link.target_text}"
` : ''} +
+
+ + + + 연결된 문서 +
+
+
${link.target_document_title}
+ ${link.target_text ? ` +
+
대상 텍스트
+
"${link.target_text}"
+
+ ` : ''} + ${link.description ? ` +
+
설명
+
${link.description}
+
+ ` : ''}
-
+
-
+
@@ -544,35 +582,67 @@ class LinkManager { const tooltip = document.createElement('div'); tooltip.id = 'backlink-tooltip'; - tooltip.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-4 z-50 max-w-lg'; - tooltip.style.minWidth = '350px'; + tooltip.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-5 z-50 max-w-2xl'; + tooltip.style.minWidth = '450px'; + tooltip.style.maxHeight = '80vh'; + tooltip.style.overflowY = 'auto'; + + // 생성 날짜 포맷팅 + const createdDate = backlink.created_at ? this.formatDate(backlink.created_at) : '알 수 없음'; const tooltipHTML = `
-
백링크 정보
-
- "${backlink.target_text || backlink.selected_text}" +
+
+ + + + 백링크 정보 +
+
${createdDate}
+
+ +
+
현재 문서의 텍스트
+
"${backlink.target_text || backlink.selected_text}"
-
-
참조 문서
-
-
${backlink.source_document_title}
-
원본 텍스트: "${backlink.selected_text}"
+
+
+ + + + 참조하는 문서 +
+
+
${backlink.source_document_title}
+
+
원본 텍스트
+
"${backlink.selected_text}"
+
+ ${backlink.description ? ` +
+
설명
+
${backlink.description}
+
+ ` : ''}
-
+
-
+
@@ -582,6 +652,32 @@ class LinkManager { this.positionTooltip(tooltip, element); } + /** + * 날짜 포맷팅 + */ + formatDate(dateString) { + if (!dateString) return '알 수 없음'; + + const date = new Date(dateString); + const now = new Date(); + const diffTime = Math.abs(now - date); + const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + + if (diffDays === 1) { + return '오늘'; + } else if (diffDays <= 7) { + return `${diffDays}일 전`; + } else if (diffDays <= 30) { + return `${Math.ceil(diffDays / 7)}주 전`; + } else { + return date.toLocaleDateString('ko-KR', { + year: 'numeric', + month: 'short', + day: 'numeric' + }); + } + } + /** * 툴팁 위치 설정 */ @@ -803,12 +899,18 @@ class LinkManager { const menu = document.createElement('div'); menu.id = 'overlap-menu'; - menu.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-2 z-50'; - menu.style.minWidth = '200px'; + menu.className = 'absolute bg-white border border-gray-300 rounded-lg shadow-lg p-4 z-50'; + menu.style.minWidth = '320px'; + menu.style.maxWidth = '400px'; let menuHTML = ` -
여러 요소가 겹쳐있습니다
-
+
+ + + + 겹치는 요소들 +
+
`; // 클릭된 요소 추가 @@ -884,25 +986,95 @@ class LinkManager { const clickedClass = isClicked ? 'ring-2 ring-blue-300' : ''; const elementId = element.dataset.highlightId || element.dataset.linkId || element.dataset.backlinkId || ''; + + + // 각 타입별 액션 버튼들 + let actionButtons = ''; + if (type === 'highlight') { + actionButtons = ` +
+ +
+ `; + } else if (type === 'link') { + actionButtons = ` +
+ + +
+ `; + } else if (type === 'backlink') { + actionButtons = ` +
+ + +
+ `; + } + return ` - + ${actionButtons} +
`; } + /** + * 메뉴에서 바로 링크된 문서로 이동 + */ + navigateToLinkedDocumentFromMenu(elementId) { + this.hideTooltip(); + + const link = this.documentLinks.find(l => l.id === elementId); + if (link) { + this.navigateToLinkedDocument(link.target_document_id, link); + } else { + console.warn('링크 데이터를 찾을 수 없음:', elementId); + } + } + + /** + * 메뉴에서 바로 소스 문서로 이동 + */ + navigateToSourceDocumentFromMenu(elementId) { + this.hideTooltip(); + + const backlink = this.backlinks.find(b => b.id === elementId); + if (backlink) { + this.navigateToSourceDocument(backlink.source_document_id, backlink); + } else { + console.warn('백링크 데이터를 찾을 수 없음:', elementId); + } + } + /** * 겹침 메뉴 클릭 처리 */ handleOverlapMenuClick(type, elementId) { + this.hideTooltip(); // 해당 요소 찾기 @@ -913,20 +1085,19 @@ class LinkManager { // 하이라이트 클릭 처리 (HighlightManager에 위임) const highlightId = elementId; - // 해당 하이라이트 그룹 찾기 - const highlightGroups = window.documentViewerInstance.highlightManager.highlightGroups || []; - const targetGroup = highlightGroups.find(group => - group.some(h => h.id === highlightId) - ); + // 해당 하이라이트 찾기 + const highlight = window.documentViewerInstance.highlightManager.highlights.find(h => h.id === highlightId); - if (targetGroup) { - window.documentViewerInstance.highlightManager.showHighlightModal(targetGroup); + if (highlight) { + // 하이라이트 툴팁 표시 (메모 작성/편집 기능 포함) + window.documentViewerInstance.highlightManager.showHighlightTooltip(highlight, element); } else { - console.warn('하이라이트 그룹을 찾을 수 없음:', highlightId); + console.warn('하이라이트를 찾을 수 없음:', highlightId); } } } else if (type === 'link') { element = document.querySelector(`[data-link-id="${elementId}"]`); + if (element) { // 링크 데이터 찾기 const link = this.documentLinks.find(l => l.id === elementId); @@ -936,6 +1107,7 @@ class LinkManager { } } else if (type === 'backlink') { element = document.querySelector(`[data-backlink-id="${elementId}"]`); + if (element) { // 백링크 데이터 찾기 const backlink = this.backlinks.find(b => b.id === elementId);