first commit
This commit is contained in:
86
src/components/left-area/NotebookNode.vue
Normal file
86
src/components/left-area/NotebookNode.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user