🐛 Fix Alpine.js SyntaxError and backlink visibility issues

- Fix SyntaxError in viewer.js line 2868 (.bind(this) issue in setTimeout)
- Resolve Alpine.js 'Can't find variable' errors (documentViewer, goBack, etc.)
- Fix backlink rendering and persistence during temporary highlights
- Add backlink protection and restoration mechanism in highlightAndScrollToText
- Implement Note Management System with hierarchical notebooks
- Add note highlights and memos functionality
- Update cache version to force browser refresh (v=2025012641)
- Add comprehensive logging for debugging backlink issues
This commit is contained in:
Hyungi Ahn
2025-08-26 23:50:48 +09:00
parent 8d7f4c04bb
commit 3e0a03f149
31 changed files with 5176 additions and 567 deletions

View File

@@ -6,7 +6,6 @@
<title>문서 뷰어 - Document Server</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📄</text></svg>">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdn.quilljs.com/1.3.6/quill.min.js"></script>
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
@@ -332,23 +331,34 @@
<!-- 링크 목록 -->
<template x-for="link in documentLinks" :key="link.id">
<div class="bg-gray-50 rounded-xl p-4 mb-4 hover:bg-gray-100 transition-colors">
<div class="flex items-start justify-between">
<div class="border rounded-lg p-4 mb-3 hover:bg-purple-50 cursor-pointer transition-colors"
@click="navigateToLink(link)">
<div class="flex items-center justify-between">
<div class="flex-1">
<h4 class="font-semibold text-gray-900 mb-2" x-text="link.target_document_title"></h4>
<p class="text-sm text-gray-600 mb-2" x-text="link.selected_text"></p>
<p class="text-sm text-gray-500" x-text="link.description || '설명 없음'"></p>
<p class="text-xs text-gray-400 mt-2" x-text="new Date(link.created_at).toLocaleDateString()"></p>
<div class="font-medium text-purple-700 mb-1" x-text="link.target_document_title"></div>
<!-- 선택된 텍스트 또는 문서 전체 링크 -->
<div x-show="link.selected_text" class="mb-2">
<div class="text-sm text-gray-600 bg-gray-100 px-3 py-2 rounded border-l-4 border-purple-500" x-text="link.selected_text"></div>
</div>
<div x-show="!link.selected_text" class="mb-2">
<div class="text-sm text-gray-600 italic">📄 문서 전체 링크</div>
</div>
<!-- 설명 -->
<div x-show="link.description" class="text-sm text-gray-600 mb-2" x-text="link.description"></div>
<!-- 링크 타입과 날짜 -->
<div class="flex items-center justify-between">
<span class="text-xs text-gray-500"
x-text="link.link_type === 'text_fragment' ? '텍스트 조각 링크' : '문서 링크'"></span>
<span class="text-xs text-gray-500" x-text="formatDate(link.created_at)"></span>
</div>
</div>
<div class="ml-4 flex space-x-2">
<button @click="navigateToLink(link)"
class="px-3 py-1 bg-purple-500 text-white text-sm rounded-lg hover:bg-purple-600 transition-colors">
이동
</button>
<button @click="deleteDocumentLink(link.id)"
class="px-3 py-1 bg-red-500 text-white text-sm rounded-lg hover:bg-red-600 transition-colors">
삭제
</button>
<div class="ml-3">
<svg class="w-5 h-5 text-purple-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
</svg>
</div>
</div>
</div>
@@ -701,8 +711,13 @@
<p class="text-sm text-orange-800 font-medium" x-text="backlink.source_document_title"></p>
</div>
<!-- 선택된 텍스트 -->
<p class="text-gray-800 mb-2 leading-relaxed" x-text="backlink.selected_text"></p>
<!-- 선택된 텍스트 또는 문서 전체 링크 -->
<div x-show="backlink.selected_text" class="mb-2">
<p class="text-gray-800 leading-relaxed" x-text="backlink.selected_text"></p>
</div>
<div x-show="!backlink.selected_text" class="mb-2">
<p class="text-gray-600 italic">📄 문서 전체 링크</p>
</div>
<!-- 설명 -->
<p class="text-sm text-gray-600 mb-2" x-text="backlink.description || '설명 없음'"></p>
@@ -723,12 +738,70 @@
</div>
<!-- 스크립트 -->
<script src="/static/js/api.js?v=2025012415"></script>
<script src="/static/js/viewer.js?v=2025012458"></script>
<script src="/static/js/api.js?v=2025012614"></script>
<script src="/static/js/viewer.js?v=2025012641"></script>
<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
<style>
[x-cloak] { display: none !important; }
/* 백링크 강제 스타일 */
.backlink-highlight {
color: #EA580C !important;
background-color: rgba(234, 88, 12, 0.3) !important;
border: 3px solid #EA580C !important;
border-radius: 6px !important;
padding: 6px 8px !important;
font-weight: bold !important;
text-decoration: underline !important;
cursor: pointer !important;
box-shadow: 0 4px 8px rgba(234, 88, 12, 0.4) !important;
display: inline-block !important;
margin: 2px !important;
}
/* 하이라이트 스타일 개선 */
.highlight {
padding: 1px 2px;
border-radius: 2px;
cursor: pointer;
transition: all 0.2s ease;
}
.highlight:hover {
box-shadow: 0 0 4px rgba(0,0,0,0.3);
transform: scale(1.02);
}
.multi-highlight {
padding: 1px 2px;
border-radius: 2px;
cursor: pointer;
transition: all 0.2s ease;
position: relative;
}
.multi-highlight:hover {
box-shadow: 0 0 6px rgba(0,0,0,0.4);
transform: scale(1.02);
}
.multi-highlight::after {
content: "🎨";
position: absolute;
top: -8px;
right: -8px;
font-size: 10px;
background: white;
border-radius: 50%;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
/* 기존 언어 전환 버튼 숨기기 */
.language-toggle-old,
button[onclick*="toggleLanguage"],