This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/src/js/sw/components/notes-pane/index.js
gobha c687002015 Changeset 0.37.11 (#223)
Co-authored-by: gobha <jasafpro@gmail.com>
Co-committed-by: gobha <jasafpro@gmail.com>
2026-03-22 00:57:49 +00:00

202 lines
8.5 KiB
JavaScript

// ==========================================
// NotesPane Kit — Default Assembly
// ==========================================
// Wires useNotes + all sub-components into the standard
// notes experience. Surfaces that need a different
// layout import individual pieces instead.
//
// Usage:
// import { NotesPane } from './components/notes-pane/index.js';
// html`<${NotesPane} handleRef=${ref} standalone=${true} />`
//
// Re-exports all pieces for kit consumers:
// import { useNotes, NoteList, NoteEditor, ... } from './components/notes-pane/index.js';
import { useNotes } from './use-notes.js';
import { NoteList } from './note-list.js';
import { NoteListItem } from './note-list-item.js';
import { NoteEditor } from './note-editor.js';
import { NoteReader } from './note-reader.js';
import { QuickSwitcher, saveRecentNote } from './quick-switcher.js';
import { SaveToNoteDialog } from './save-to-note.js';
import { renderNoteMarkdown, attachWikilinkHandlers, resolveTransclusions, extractHeadings } from './markdown.js';
const { useState, useRef, useEffect, useCallback } = window.hooks;
const html = window.html;
/**
* Default NotesPane assembly.
*
* @param {{
* initialFolder?: string,
* initialNoteId?: string,
* standalone?: boolean,
* onNoteChange?: (note: object|null) => void,
* handleRef?: { current: any },
* className?: string,
* }} props
*/
export function NotesPane(props) {
const {
initialFolder,
initialNoteId,
standalone = true,
onNoteChange,
handleRef,
className,
} = props;
const notes = useNotes({
initialFolder,
initialNoteId,
onNoteChange,
standalone,
enableGraph: true,
enableQuickSwitcher: true,
});
// ── Lazy-load graph component ───────────
const [GraphComp, setGraphComp] = useState(null);
useEffect(() => {
if (notes.view === 'graph' && !GraphComp) {
import('./note-graph.js').then(m => setGraphComp(() => m.NoteGraph));
}
}, [notes.view, GraphComp]);
const graphHandleRef = useRef(null);
// ── Graph data loading ──────────────────
useEffect(() => {
if (notes.view === 'graph' && !notes.graphData) {
notes.loadGraph();
}
}, [notes.view]);
// ── Expose imperative handle ────────────
useEffect(() => {
if (handleRef) {
handleRef.current = {
getView() { return notes.view; },
setView(v) { notes.setView(v); },
openNote(id) { saveRecentNote({ id, title: '' }); notes.openNote(id); },
newNote() { notes.newNote(); },
openDailyNote() { notes.openDailyNote(); },
refreshList() { notes.refreshList(); },
getEditingId() { return notes.editingId; },
openQuickSwitcher() { notes.setQuickSwitcherOpen(true); },
// Surface-driven filter controls (v0.37.11)
setFolder(f) { notes.setFolder(f); },
setTagFilter(t) { notes.setTagFilter(t); },
setSearchQuery(q) { notes.setSearchQuery(q); },
getFolder() { return notes.folder; },
getTagFilter() { return notes.tagFilter; },
};
}
});
// ── Quick switcher create-new handler ───
const onQuickSwitcherCreate = useCallback((title) => {
notes.newNote();
// The editor will open blank — we can't pre-fill via state here
// but the title will be empty for the user to type
}, [notes.newNote]);
// ── View routing ────────────────────────
const renderView = () => {
switch (notes.view) {
case 'list':
return html`
<${NoteList}
notes=${notes.notes} loading=${notes.loading}
hasMore=${notes.hasMore} loadMore=${notes.loadMore}
folders=${notes.folders} folder=${notes.folder} setFolder=${notes.setFolder}
sort=${notes.sort} setSort=${notes.setSort}
searchQuery=${notes.searchQuery} setSearchQuery=${notes.setSearchQuery}
tagFilter=${notes.tagFilter} setTagFilter=${notes.setTagFilter}
selectMode=${notes.selectMode} selectedIds=${notes.selectedIds}
enterSelectMode=${notes.enterSelectMode} exitSelectMode=${notes.exitSelectMode}
toggleSelect=${notes.toggleSelect} toggleSelectAll=${notes.toggleSelectAll}
bulkDelete=${notes.bulkDelete}
onNoteClick=${(id) => { saveRecentNote({ id, title: '' }); notes.openNote(id); }}
onNewNote=${notes.newNote}
onDailyNote=${notes.openDailyNote}
onGraphClick=${() => notes.setView('graph')}
pinnedIds=${notes.pinnedIds} togglePin=${notes.togglePin}
standalone=${standalone} />`;
case 'editor':
return html`
<${NoteEditor}
currentNote=${notes.currentNote}
editingId=${notes.editingId}
folders=${notes.folders}
onSave=${notes.saveNote}
onCancel=${() => {
if (notes.currentNote) {
notes.setEditorMode('read');
notes.setView('reader');
} else {
notes.setView('list');
notes.refreshList();
}
}}
onDelete=${notes.deleteNote} />`;
case 'reader':
return html`
<${NoteReader}
note=${notes.currentNote}
backlinks=${notes.backlinks}
onEdit=${() => {
notes.setEditorMode('edit');
notes.setView('editor');
}}
onDelete=${notes.deleteNote}
onCopy=${notes.copyNote}
onNavigateLink=${notes.navigateToLink}
onBack=${() => { notes.setView('list'); notes.refreshList(); }}
isDailyNote=${notes.isDailyNote}
onDailyPrev=${() => notes.navigateDaily(-1)}
onDailyNext=${() => notes.navigateDaily(1)} />`;
case 'graph':
if (!GraphComp) {
return html`<div class="sw-notes-pane__loading">Loading graph\u2026</div>`;
}
return html`
<${GraphComp}
data=${notes.graphData}
onNodeClick=${(id) => { notes.openNote(id); }}
onGhostClick=${(title) => { notes.navigateToLink(title); }}
onBack=${() => notes.setView('list')}
handleRef=${graphHandleRef} />`;
default:
return null;
}
};
return html`
<div class=${'sw-notes-pane' + (className ? ' ' + className : '')}>
${renderView()}
<${QuickSwitcher}
open=${notes.quickSwitcherOpen}
onClose=${() => notes.setQuickSwitcherOpen(false)}
onSelect=${(id) => notes.openNote(id)}
onCreateNew=${onQuickSwitcherCreate} />
</div>
`;
}
// ── Kit re-exports ─────────────────────────
export { useNotes } from './use-notes.js';
export { NoteList } from './note-list.js';
export { NoteListItem } from './note-list-item.js';
export { NoteEditor } from './note-editor.js';
export { NoteReader } from './note-reader.js';
export { NoteGraph } from './note-graph.js';
export { QuickSwitcher, saveRecentNote } from './quick-switcher.js';
export { SaveToNoteDialog } from './save-to-note.js';
export { renderNoteMarkdown, attachWikilinkHandlers, resolveTransclusions, extractHeadings } from './markdown.js';