🔧 검색 미리보기 기능 수정
- API 호출 방식 개선 (fetch 직접 사용) - HTML 응답에서 텍스트 추출 로직 추가 - 미리보기 모달 UX 개선 (ESC 키, 클릭으로 닫기) - 내용 표시 최적화 (스크롤, 워드랩) - 에러 처리 강화 (fallback to original content)
This commit is contained in:
@@ -406,6 +406,8 @@
|
|||||||
|
|
||||||
<!-- 미리보기 모달 -->
|
<!-- 미리보기 모달 -->
|
||||||
<div x-show="showPreviewModal"
|
<div x-show="showPreviewModal"
|
||||||
|
@keydown.escape.window="closePreview()"
|
||||||
|
@click.self="closePreview()"
|
||||||
x-transition:enter="transition ease-out duration-300"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-transition:enter-start="opacity-0"
|
x-transition:enter-start="opacity-0"
|
||||||
x-transition:enter-end="opacity-100"
|
x-transition:enter-end="opacity-100"
|
||||||
@@ -473,10 +475,19 @@
|
|||||||
|
|
||||||
<!-- 본문 내용 -->
|
<!-- 본문 내용 -->
|
||||||
<div class="prose max-w-none">
|
<div class="prose max-w-none">
|
||||||
<div class="text-gray-700 leading-relaxed whitespace-pre-wrap"
|
<div class="text-gray-700 leading-relaxed"
|
||||||
|
style="white-space: pre-wrap; word-wrap: break-word; max-height: 400px; overflow-y: auto;"
|
||||||
x-html="highlightText(previewResult?.content || '', searchQuery)"></div>
|
x-html="highlightText(previewResult?.content || '', searchQuery)"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 추가 정보 -->
|
||||||
|
<div x-show="previewResult?.type === 'memo'" class="mt-4 p-3 bg-purple-50 border border-purple-200 rounded-lg">
|
||||||
|
<div class="text-sm font-medium text-purple-800 mb-1">
|
||||||
|
<i class="fas fa-tree mr-2"></i>메모 트리 정보
|
||||||
|
</div>
|
||||||
|
<div class="text-purple-700 text-sm" x-text="previewResult?.document_title"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 로딩 상태 -->
|
<!-- 로딩 상태 -->
|
||||||
<div x-show="previewLoading" class="text-center py-8">
|
<div x-show="previewLoading" class="text-center py-8">
|
||||||
<i class="fas fa-spinner fa-spin text-2xl text-gray-400 mb-2"></i>
|
<i class="fas fa-spinner fa-spin text-2xl text-gray-400 mb-2"></i>
|
||||||
|
|||||||
@@ -215,15 +215,54 @@ window.searchApp = function() {
|
|||||||
|
|
||||||
switch (result.type) {
|
switch (result.type) {
|
||||||
case 'document':
|
case 'document':
|
||||||
// 문서 내용 API 호출
|
case 'document_content':
|
||||||
const docContent = await this.api.get(`/documents/${result.document_id}/content`);
|
try {
|
||||||
content = docContent;
|
// 문서 내용 API 호출 (HTML 응답)
|
||||||
|
const response = await fetch(`/api/documents/${result.document_id}/content`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${localStorage.getItem('token')}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const htmlContent = await response.text();
|
||||||
|
// HTML에서 텍스트만 추출
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(htmlContent, 'text/html');
|
||||||
|
content = doc.body.textContent || doc.body.innerText || '';
|
||||||
|
// 너무 길면 자르기
|
||||||
|
if (content.length > 2000) {
|
||||||
|
content = content.substring(0, 2000) + '...';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content = result.content;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('문서 내용 로드 실패, 기본 내용 사용:', err);
|
||||||
|
content = result.content;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'note':
|
case 'note':
|
||||||
|
try {
|
||||||
// 노트 내용 API 호출
|
// 노트 내용 API 호출
|
||||||
const noteContent = await this.api.get(`/note-documents/${result.id}/content`);
|
const noteContent = await this.api.get(`/note-documents/${result.id}/content`);
|
||||||
content = noteContent;
|
content = noteContent;
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('노트 내용 로드 실패, 기본 내용 사용:', err);
|
||||||
|
content = result.content;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'memo':
|
||||||
|
try {
|
||||||
|
// 메모 노드 상세 정보 로드
|
||||||
|
const memoNode = await this.api.get(`/memo-trees/nodes/${result.id}`);
|
||||||
|
content = memoNode.content || result.content;
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('메모 내용 로드 실패, 기본 내용 사용:', err);
|
||||||
|
content = result.content;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user