feat: implement create new type feature
Core implementation: - CreateTypeDialog: simple dialog with name field for creating new types - handleCreateType in useNoteActions: creates Type documents in type/ folder - Dynamic sidebar sections: custom types (Recipe, Book, etc.) appear as new sidebar sections after built-in ones, each with a + button for instances - Updated CreateNoteDialog: accepts custom types, shows them with blue accent - handleCreateNote now supports custom types (folder = lowercased type name) Product decisions: - The + on Types section opens CreateTypeDialog (not CreateNoteDialog) - Custom type sections use FileText icon and blue accent color by default - Section labels are pluralized (e.g., "Recipes", "Books") Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,6 @@ import { invoke } from '@tauri-apps/api/core'
|
||||
import { isTauri, mockInvoke, addMockEntry, updateMockContent } from '../mock-tauri'
|
||||
import type { VaultEntry } from '../types'
|
||||
import type { FrontmatterValue } from '../components/Inspector'
|
||||
import type { NoteType } from '../components/CreateNoteDialog'
|
||||
|
||||
interface Tab {
|
||||
entry: VaultEntry
|
||||
@@ -173,21 +172,23 @@ export function useNoteActions(
|
||||
}
|
||||
}, [entries, handleSelectNote])
|
||||
|
||||
const handleCreateNote = useCallback(async (title: string, type: NoteType) => {
|
||||
const handleCreateNote = useCallback(async (title: string, type: string) => {
|
||||
const typeToFolder: Record<string, string> = {
|
||||
Note: 'note', Project: 'project', Experiment: 'experiment',
|
||||
Responsibility: 'responsibility', Procedure: 'procedure',
|
||||
Person: 'person', Event: 'event', Topic: 'topic',
|
||||
}
|
||||
const folder = typeToFolder[type] || 'note'
|
||||
// Custom types use lowercased type name as folder
|
||||
const folder = typeToFolder[type] || type.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '')
|
||||
const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '')
|
||||
const path = `/Users/luca/Laputa/${folder}/${slug}.md`
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
|
||||
const noStatusTypes = new Set(['Topic', 'Person'])
|
||||
const newEntry: VaultEntry = {
|
||||
path, filename: `${slug}.md`, title, isA: type,
|
||||
aliases: [], belongsTo: [], relatedTo: [],
|
||||
status: type === 'Topic' || type === 'Person' ? null : 'Active',
|
||||
status: noStatusTypes.has(type) ? null : 'Active',
|
||||
owner: null, cadence: null, modifiedAt: now, createdAt: now, fileSize: 0,
|
||||
snippet: '', relationships: {},
|
||||
}
|
||||
@@ -207,6 +208,29 @@ export function useNoteActions(
|
||||
handleSelectNote(newEntry)
|
||||
}, [handleSelectNote, addEntry])
|
||||
|
||||
const handleCreateType = useCallback(async (typeName: string) => {
|
||||
const slug = typeName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '')
|
||||
const path = `/Users/luca/Laputa/type/${slug}.md`
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
|
||||
const newEntry: VaultEntry = {
|
||||
path, filename: `${slug}.md`, title: typeName, isA: 'Type',
|
||||
aliases: [], belongsTo: [], relatedTo: [],
|
||||
status: null, owner: null, cadence: null,
|
||||
modifiedAt: now, createdAt: now, fileSize: 0,
|
||||
snippet: '', relationships: {},
|
||||
}
|
||||
|
||||
const content = `---\nIs A: Type\n---\n\n# ${typeName}\n\n`
|
||||
|
||||
if (!isTauri()) {
|
||||
addMockEntry(newEntry, content)
|
||||
}
|
||||
|
||||
addEntry(newEntry, content)
|
||||
handleSelectNote(newEntry)
|
||||
}, [handleSelectNote, addEntry])
|
||||
|
||||
const handleUpdateFrontmatter = useCallback(async (path: string, key: string, value: FrontmatterValue) => {
|
||||
try {
|
||||
let newContent: string
|
||||
@@ -272,6 +296,7 @@ export function useNoteActions(
|
||||
handleSwitchTab,
|
||||
handleNavigateWikilink,
|
||||
handleCreateNote,
|
||||
handleCreateType,
|
||||
handleUpdateFrontmatter,
|
||||
handleDeleteProperty,
|
||||
handleAddProperty,
|
||||
|
||||
Reference in New Issue
Block a user