diff --git a/frontend/src/lib/components/DocumentViewer.svelte b/frontend/src/lib/components/DocumentViewer.svelte new file mode 100644 index 0000000..447e150 --- /dev/null +++ b/frontend/src/lib/components/DocumentViewer.svelte @@ -0,0 +1,80 @@ + + +
+ {#if loading} +
+

로딩 중...

+
+ {:else if fullDoc} + {#if viewerType === 'markdown' || viewerType === 'hwp-markdown'} +
+ {@html marked(fullDoc.extracted_text || '*텍스트 추출 대기 중*')} +
+ {:else if viewerType === 'pdf'} + + {:else if viewerType === 'image'} +
+ {fullDoc.title} +
+ {:else if viewerType === 'synology'} + + {:else} +
+
+

미리보기를 지원하지 않는 형식입니다

+

{fullDoc.file_format}

+
+
+ {/if} + {/if} +
diff --git a/frontend/src/routes/documents/+page.svelte b/frontend/src/routes/documents/+page.svelte index bfdf3e0..be9e74b 100644 --- a/frontend/src/routes/documents/+page.svelte +++ b/frontend/src/routes/documents/+page.svelte @@ -5,14 +5,15 @@ import { addToast } from '$lib/stores/ui'; import DocumentCard from '$lib/components/DocumentCard.svelte'; import PreviewPanel from '$lib/components/PreviewPanel.svelte'; + import DocumentViewer from '$lib/components/DocumentViewer.svelte'; let documents = $state([]); - let selectedDoc = $state(null); let total = $state(0); let loading = $state(true); let searchQuery = $state(''); let searchMode = $state('hybrid'); let searchResults = $state(null); + let selectedDoc = $state(null); let debounceTimer; // URL params → filter (source of truth) @@ -30,8 +31,7 @@ searchQuery = urlQ; searchMode = urlMode; - - selectedDoc = null; // 필터 변경 시 선택 해제 + selectedDoc = null; if (urlQ) { doSearch(urlQ, urlMode); @@ -113,116 +113,123 @@ searchQuery = ''; } - let totalPages = $derived(Math.ceil(total / 20)); - let items = $derived(searchResults || documents); - let hasActiveFilters = $derived(!!filterDomain || !!filterSubGroup || !!searchQuery); - function selectDoc(doc) { selectedDoc = selectedDoc?.id === doc.id ? null : doc; } + + let totalPages = $derived(Math.ceil(total / 20)); + let items = $derived(searchResults || documents); + let hasActiveFilters = $derived(!!filterDomain || !!filterSubGroup || !!searchQuery); -
- -
- -
- - -
+
+ +
+ +
+ + +
- - {#if !loading} -
-
- {total}건 - {#if filterDomain} - - {filterDomain.replace('Knowledge/', '')}{filterSubGroup ? ` / ${filterSubGroup}` : ''} - + + {#if !loading} +
+
+ {total}건 + {#if filterDomain} + + {filterDomain.replace('Knowledge/', '')}{filterSubGroup ? ` / ${filterSubGroup}` : ''} + + {/if} +
+ {#if hasActiveFilters} + {/if}
- {#if hasActiveFilters} - - {/if} -
- {/if} + {/if} - - {#if loading} -
- {#each Array(6) as _} -
- {/each} -
- {:else if items.length === 0} -
- {#if searchQuery} -

'{searchQuery}'에 대한 결과가 없습니다

-

다른 검색어를 시도하거나 검색 모드를 변경해보세요

- - {:else if hasActiveFilters} -

이 분류에 문서가 없습니다

- - {:else} -

등록된 문서가 없습니다

-

문서를 업로드하거나 Inbox에 추가하세요

- {/if} -
- {:else} -
- {#each items as doc} - - {/each} -
- - - {#if !searchResults && totalPages > 1} -
- {#each Array(totalPages) as _, i} - + + {#if loading} +
+ {#each Array(6) as _} +
{/each}
+ {:else if items.length === 0} +
+ {#if searchQuery} +

'{searchQuery}'에 대한 결과가 없습니다

+

다른 검색어를 시도하거나 검색 모드를 변경해보세요

+ + {:else if hasActiveFilters} +

이 분류에 문서가 없습니다

+ + {:else} +

등록된 문서가 없습니다

+

문서를 업로드하거나 Inbox에 추가하세요

+ {/if} +
+ {:else} +
+ {#each items as doc} + + {/each} +
+ + + {#if !searchResults && totalPages > 1} +
+ {#each Array(totalPages) as _, i} + + {/each} +
+ {/if} {/if} +
+ + + {#if selectedDoc} +
+ +
+ +
+ + +
{/if}
- - -{#if selectedDoc} - -{/if} -