87 lines
2.4 KiB
Vue
87 lines
2.4 KiB
Vue
<script setup>
|
|
import { ref, onMounted } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useNotebooksStore } from '@/stores/notebooks'
|
|
import { useNotesStore } from '@/stores/notes'
|
|
import { ChevronRight, Folder, FolderOpen } from 'lucide-vue-next'
|
|
import NoteItem from './NoteItem.vue'
|
|
|
|
const props = defineProps({
|
|
notebook: { type: Object, required: true },
|
|
level: { type: Number, default: 0 },
|
|
})
|
|
|
|
const router = useRouter()
|
|
const notebooksStore = useNotebooksStore()
|
|
const notesStore = useNotesStore()
|
|
const notes = ref([])
|
|
|
|
const isExpanded = () => notebooksStore.isExpanded(props.notebook.path)
|
|
|
|
function toggle() {
|
|
notebooksStore.toggleExpand(props.notebook.path)
|
|
}
|
|
|
|
async function loadNotes() {
|
|
const entries = await window.tunjiAPI.file.list(props.notebook.path)
|
|
notes.value = entries
|
|
.filter(e => e.isFile && e.name.endsWith('.md'))
|
|
.map(e => ({
|
|
id: e.name.replace('.md', ''),
|
|
title: e.name.replace('.md', ''),
|
|
filePath: e.path,
|
|
}))
|
|
}
|
|
|
|
function openNote(note) {
|
|
router.push({ name: 'note-detail', params: { id: note.id } })
|
|
}
|
|
|
|
onMounted(loadNotes)
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<!-- 笔记本节点 -->
|
|
<button
|
|
class="w-full flex items-center gap-1.5 px-2 py-1.5 rounded-md text-sm transition-colors"
|
|
:style="{ paddingLeft: (level * 12 + 8) + 'px', color: 'var(--p-surface-600)' }"
|
|
@click="toggle"
|
|
@mouseenter="$event.target.style.backgroundColor = 'var(--p-surface-100)'"
|
|
@mouseleave="$event.target.style.backgroundColor = 'transparent'"
|
|
>
|
|
<ChevronRight
|
|
:size="14"
|
|
class="transition-transform flex-shrink-0"
|
|
:class="{ 'rotate-90': isExpanded() }"
|
|
:style="{ color: 'var(--p-surface-400)' }"
|
|
/>
|
|
<component
|
|
:is="isExpanded() ? FolderOpen : Folder"
|
|
:size="16"
|
|
:style="{ color: 'var(--p-primary-500)' }"
|
|
/>
|
|
<span class="truncate">{{ notebook.name }}</span>
|
|
</button>
|
|
|
|
<!-- 子内容 -->
|
|
<div v-if="isExpanded()">
|
|
<!-- 子笔记本 -->
|
|
<NotebookNode
|
|
v-for="child in notebook.children"
|
|
:key="child.path"
|
|
:notebook="child"
|
|
:level="level + 1"
|
|
/>
|
|
<!-- 笔记列表 -->
|
|
<NoteItem
|
|
v-for="note in notes"
|
|
:key="note.id"
|
|
:note="note"
|
|
:level="level + 1"
|
|
@click="openNote(note)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|