Add section grouping to shared note tabs
Notes can now be clustered into named sections in the tab bar: each tab gets a 🏷 button to assign it to a section, and clicking a section's label renames (or, given an empty name, ungroups) every page in it. note_pages gains a `section` column. Since the app has no migration framework, database.py adds the column to existing SQLite files at startup via PRAGMA table_info + ALTER TABLE. core/notes.set_section() keeps same-section pages contiguous by renumbering position whenever a page's section changes, so the tab bar and the AI-facing title list (now grouped under "## section" headings) can both treat "adjacent" as "same group" without a separate ordering field. Also fixes a bug in the tab rename input: ref="renameInput" sits inside a nested v-for, which Vue 3 binds as an array rather than a single element, so renameInput.value?.select() was throwing on every rename. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
createNotePage,
|
||||
updateNotePage,
|
||||
deleteNotePage,
|
||||
renameNoteSection,
|
||||
type NotePage,
|
||||
} from '../api/client'
|
||||
|
||||
@@ -44,17 +45,42 @@ export const useNotesStore = defineStore('notes', () => {
|
||||
activeId.value = id
|
||||
}
|
||||
|
||||
async function addPage(title = '新しいページ'): Promise<void> {
|
||||
async function addPage(title = '新しいページ', section: string | null = null): Promise<void> {
|
||||
error.value = null
|
||||
try {
|
||||
const page = await createNotePage(title)
|
||||
pages.value.push(page)
|
||||
const page = await createNotePage(title, section)
|
||||
// サーバー側でセクションの並びに合わせて再配置されている可能性があるため一覧を取り直す
|
||||
await load()
|
||||
activeId.value = page.id
|
||||
} catch (e) {
|
||||
error.value = e instanceof Error ? e.message : 'ページの作成に失敗しました'
|
||||
}
|
||||
}
|
||||
|
||||
/** ページの所属セクションを変更する。section が空/nullならグループ解除。並び順もサーバー側で調整されるため再取得する。 */
|
||||
async function setSection(id: number, section: string | null): Promise<void> {
|
||||
error.value = null
|
||||
flush()
|
||||
try {
|
||||
await updateNotePage(id, { section })
|
||||
await load()
|
||||
} catch (e) {
|
||||
error.value = e instanceof Error ? e.message : 'セクションの変更に失敗しました'
|
||||
}
|
||||
}
|
||||
|
||||
/** oldName セクションに属する全ページを newName セクションへ一括で付け替える。newName が空ならグループ解除。 */
|
||||
async function renameSection(oldName: string, newName: string | null): Promise<void> {
|
||||
error.value = null
|
||||
flush()
|
||||
try {
|
||||
await renameNoteSection(oldName, newName)
|
||||
await load()
|
||||
} catch (e) {
|
||||
error.value = e instanceof Error ? e.message : 'セクション名の変更に失敗しました'
|
||||
}
|
||||
}
|
||||
|
||||
async function removePage(id: number): Promise<void> {
|
||||
error.value = null
|
||||
try {
|
||||
@@ -118,6 +144,8 @@ export const useNotesStore = defineStore('notes', () => {
|
||||
addPage,
|
||||
removePage,
|
||||
edit,
|
||||
setSection,
|
||||
renameSection,
|
||||
flush,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user