revert: sous-page retirée — doublon avec carnets + wikilinks
Momento a déjà une hiérarchie Carnets → Notes + wikilinks [[note]]. Les sous-pages créent une deuxième hiérarchie conflictuelle.
This commit is contained in:
122
memento-note/components/tiptap-subpage-extension.tsx
Normal file
122
memento-note/components/tiptap-subpage-extension.tsx
Normal file
@@ -0,0 +1,122 @@
|
||||
'use client'
|
||||
|
||||
import { Node, mergeAttributes } from '@tiptap/core'
|
||||
import { ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react'
|
||||
import { FileText, Trash2, ChevronRight } from 'lucide-react'
|
||||
import { useLanguage } from '@/lib/i18n'
|
||||
import { useRouter } from 'next/navigation'
|
||||
|
||||
const SubPageView = ({ node, deleteNode, selected }: any) => {
|
||||
const { t } = useLanguage()
|
||||
const router = useRouter()
|
||||
const noteId = node.attrs.noteId as string
|
||||
const title = (node.attrs.title as string) || t('notes.untitled') || 'Sans titre'
|
||||
|
||||
const open = () => {
|
||||
if (noteId) router.push(`/home?openNote=${noteId}`)
|
||||
}
|
||||
|
||||
return (
|
||||
<NodeViewWrapper className="sub-page-block my-2" dir="auto" data-selected={selected}>
|
||||
<div className="group/sub flex items-center gap-2 rounded-xl border border-border bg-card hover:border-brand-accent/40 hover:shadow-sm transition-all p-3 cursor-pointer" onClick={open}>
|
||||
<div className="w-8 h-8 rounded-lg bg-brand-accent/10 flex items-center justify-center flex-shrink-0">
|
||||
<FileText className="h-4 w-4 text-brand-accent" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-sm font-medium truncate">{title}</div>
|
||||
<div className="text-[10px] text-muted-foreground">Sous-page</div>
|
||||
</div>
|
||||
<ChevronRight className="h-4 w-4 text-muted-foreground flex-shrink-0 group-hover/sub:text-brand-accent transition-colors" />
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); deleteNode() }}
|
||||
contentEditable={false}
|
||||
className="p-1 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive opacity-0 group-hover/sub:opacity-100 transition-opacity flex-shrink-0"
|
||||
title="Supprimer"
|
||||
>
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
</NodeViewWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export const SubPageExtension = Node.create({
|
||||
name: 'subPageBlock',
|
||||
group: 'block',
|
||||
atom: true,
|
||||
defining: true,
|
||||
|
||||
addAttributes() {
|
||||
return {
|
||||
noteId: {
|
||||
default: '',
|
||||
parseHTML: (el) => el.getAttribute('data-note-id') || '',
|
||||
renderHTML: (attrs) => ({ 'data-note-id': attrs.noteId }),
|
||||
},
|
||||
title: {
|
||||
default: '',
|
||||
parseHTML: (el) => el.getAttribute('data-title') || '',
|
||||
renderHTML: (attrs) => ({ 'data-title': attrs.title }),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [{ tag: 'div[data-type="sub-page-block"]' }]
|
||||
},
|
||||
|
||||
renderHTML({ node, HTMLAttributes }) {
|
||||
return [
|
||||
'div',
|
||||
mergeAttributes(HTMLAttributes, {
|
||||
'data-type': 'sub-page-block',
|
||||
'data-note-id': node.attrs.noteId,
|
||||
'data-title': node.attrs.title,
|
||||
class: 'sub-page-block',
|
||||
}),
|
||||
]
|
||||
},
|
||||
|
||||
addNodeView() {
|
||||
return ReactNodeViewRenderer(SubPageView)
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
'Mod-Shift-P': () => this.editor.commands.insertContent({
|
||||
type: this.name,
|
||||
attrs: { noteId: '', title: '' },
|
||||
}),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export async function insertSubPageBlock(editor: any): Promise<void> {
|
||||
const notebookId = (editor.storage as any).structuredViewBlock?.notebookId as string | null
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/notes', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
title: 'Sans titre',
|
||||
content: '<p></p>',
|
||||
notebookId: notebookId || undefined,
|
||||
}),
|
||||
})
|
||||
const data = await res.json()
|
||||
|
||||
if (!res.ok || !data.data) return
|
||||
|
||||
const note = data.data
|
||||
editor.chain().focus().insertContent({
|
||||
type: 'subPageBlock',
|
||||
attrs: {
|
||||
noteId: note.id,
|
||||
title: note.title || 'Sans titre',
|
||||
},
|
||||
}).run()
|
||||
} catch (e) {
|
||||
console.error('[SubPage] Failed to create note:', e)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user