Changeset 0.22.7 (#149)
This commit is contained in:
200
src/js/notes.js
200
src/js/notes.js
@@ -744,15 +744,157 @@ function _showSaveToNoteModal(opts) {
|
||||
// ── Notes Listeners (extracted from initListeners) ──
|
||||
|
||||
function _registerNotesPanel() {
|
||||
const el = document.getElementById('sidePanelNotes');
|
||||
if (!el) return;
|
||||
const body = document.getElementById('sidePanelBody');
|
||||
if (!body || typeof PanelRegistry === 'undefined') return;
|
||||
|
||||
// ── Create the panel element dynamically ──
|
||||
const el = document.createElement('div');
|
||||
el.className = 'side-panel-page';
|
||||
el.id = 'sidePanelNotes';
|
||||
el.style.display = 'none';
|
||||
el.innerHTML = `
|
||||
<!-- List view -->
|
||||
<div id="notesListView">
|
||||
<div class="notes-toolbar">
|
||||
<button id="notesNewBtn" class="btn-small" title="New note">+ New</button>
|
||||
<button id="notesTodayBtn" class="btn-small" title="Open daily note">📅 Today</button>
|
||||
<button id="notesGraphBtn" class="btn-small" title="Note graph">🕸 Graph</button>
|
||||
<button id="notesSelectModeBtn" class="btn-small" title="Select mode">☑ Select</button>
|
||||
</div>
|
||||
<div class="notes-search-row">
|
||||
<input type="text" id="notesSearchInput" class="notes-search-input" placeholder="Search notes…" autocomplete="off">
|
||||
</div>
|
||||
<div class="notes-filter-row">
|
||||
<select id="notesFolderFilter" class="notes-filter-select"><option value="">All folders</option></select>
|
||||
<select id="notesSortSelect" class="notes-filter-select">
|
||||
<option value="updated_desc">Last updated</option>
|
||||
<option value="created_desc">Created</option>
|
||||
<option value="alpha">Alphabetical</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="notesList" class="notes-list"></div>
|
||||
<div id="notesSelectionBar" class="notes-selection-bar" style="display:none;">
|
||||
<label class="notes-select-all"><input type="checkbox" id="notesSelectAll"> All</label>
|
||||
<span id="notesSelectedCount">0</span> selected
|
||||
<button id="notesDeleteSelectedBtn" class="btn-small btn-danger">Delete</button>
|
||||
<button id="notesCancelSelectBtn" class="btn-small">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Editor view -->
|
||||
<div id="notesEditorView" style="display:none;">
|
||||
<div class="notes-editor-header">
|
||||
<button id="notesBackBtn" class="btn-small" title="Back to list">← Back</button>
|
||||
<div style="flex:1"></div>
|
||||
<button id="noteEditBtn" class="btn-small" style="display:none;">Edit</button>
|
||||
<button id="notePreviewBtn" class="btn-small" style="display:none;">Preview</button>
|
||||
<button id="noteCancelEditBtn" class="btn-small" style="display:none;">Cancel</button>
|
||||
<button id="noteDeleteBtn" class="btn-small btn-danger" style="display:none;">Delete</button>
|
||||
<button id="noteSaveBtn" class="btn-small btn-primary">Save</button>
|
||||
</div>
|
||||
<!-- Edit mode -->
|
||||
<div id="noteEditMode" class="notes-editor">
|
||||
<input type="text" id="noteEditorTitle" class="notes-title-input" placeholder="Note title">
|
||||
<div class="notes-meta-row">
|
||||
<input type="text" id="noteEditorFolder" class="notes-folder-input" placeholder="Folder (e.g. work/project)">
|
||||
<input type="text" id="noteEditorTags" class="notes-tags-input" placeholder="Tags (comma-separated)">
|
||||
</div>
|
||||
<div id="noteEditorContentContainer" class="notes-content-container">
|
||||
<textarea id="noteEditorContent" rows="12" class="notes-content-input" placeholder="Write your note in markdown…"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Read mode -->
|
||||
<div id="noteReadMode" style="display:none;">
|
||||
<div class="notes-read-view">
|
||||
<h3 id="noteReadTitle" class="note-read-title"></h3>
|
||||
<div id="noteReadMeta" class="note-read-meta"></div>
|
||||
<div id="noteReadContent" class="note-read-content msg-content"></div>
|
||||
<button id="noteDeleteBtn2" class="btn-small btn-danger" style="display:none;margin-top:8px;">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Backlinks -->
|
||||
<div id="noteBacklinks" class="note-backlinks" style="display:none;">
|
||||
<div class="note-backlinks-header" onclick="toggleBacklinks()">
|
||||
Backlinks <span id="noteBacklinksCount" class="badge">0</span>
|
||||
</div>
|
||||
<div id="noteBacklinksList" class="note-backlinks-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Graph view -->
|
||||
<div id="notesGraphView" style="display:none;"></div>`;
|
||||
body.appendChild(el);
|
||||
|
||||
// ── Wire listeners ──
|
||||
// Sidebar trigger (lives outside this panel)
|
||||
document.getElementById('notesBtn')?.addEventListener('click', openNotes);
|
||||
|
||||
// Toolbar buttons
|
||||
el.querySelector('#notesNewBtn').addEventListener('click', () => openNoteEditor(null));
|
||||
el.querySelector('#notesGraphBtn').addEventListener('click', () => {
|
||||
if (typeof openNoteGraph === 'function') openNoteGraph();
|
||||
});
|
||||
el.querySelector('#notesTodayBtn').addEventListener('click', openDailyNote);
|
||||
el.querySelector('#notesSelectModeBtn').addEventListener('click', () => {
|
||||
if (_notesSelectMode) _exitSelectMode();
|
||||
else _enterSelectMode();
|
||||
});
|
||||
|
||||
// Editor header buttons
|
||||
el.querySelector('#notesBackBtn').addEventListener('click', () => { showNotesList(); loadNotesList(); loadNoteFolders(); });
|
||||
el.querySelector('#noteSaveBtn').addEventListener('click', saveNote);
|
||||
el.querySelector('#noteDeleteBtn').addEventListener('click', deleteNote);
|
||||
el.querySelector('#noteDeleteBtn2').addEventListener('click', deleteNote);
|
||||
el.querySelector('#noteEditBtn').addEventListener('click', _showNoteEditMode);
|
||||
el.querySelector('#notePreviewBtn').addEventListener('click', _showNotePreview);
|
||||
el.querySelector('#noteCancelEditBtn').addEventListener('click', () => {
|
||||
if (_currentNote) { _populateEditFields(_currentNote); _showNoteReadMode(); }
|
||||
else showNotesList();
|
||||
});
|
||||
|
||||
// Filters
|
||||
el.querySelector('#notesFolderFilter').addEventListener('change', (e) => {
|
||||
document.getElementById('notesSearchInput').value = '';
|
||||
_exitSelectMode();
|
||||
loadNotesList(e.target.value);
|
||||
});
|
||||
el.querySelector('#notesSortSelect').addEventListener('change', (e) => {
|
||||
_notesSort = e.target.value;
|
||||
_exitSelectMode();
|
||||
loadNotesList();
|
||||
});
|
||||
|
||||
// Multi-select controls
|
||||
el.querySelector('#notesSelectAll').addEventListener('change', (e) => {
|
||||
_toggleSelectAll(e.target.checked);
|
||||
});
|
||||
el.querySelector('#notesDeleteSelectedBtn').addEventListener('click', _bulkDeleteSelected);
|
||||
el.querySelector('#notesCancelSelectBtn').addEventListener('click', _exitSelectMode);
|
||||
|
||||
// Search with debounce
|
||||
let _notesSearchTimer;
|
||||
el.querySelector('#notesSearchInput').addEventListener('input', (e) => {
|
||||
clearTimeout(_notesSearchTimer);
|
||||
const q = e.target.value.trim();
|
||||
_notesSearchTimer = setTimeout(() => {
|
||||
_exitSelectMode();
|
||||
if (q.length >= 2) {
|
||||
document.getElementById('notesFolderFilter').value = '';
|
||||
loadNotesList(null, q);
|
||||
} else if (q.length === 0) {
|
||||
loadNotesList();
|
||||
}
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// ── Register with PanelRegistry ──
|
||||
PanelRegistry.register('notes', {
|
||||
element: el,
|
||||
label: 'Notes',
|
||||
onOpen() {
|
||||
// Loading is handled by openNotes() which calls loadNotesList
|
||||
},
|
||||
onClose() {
|
||||
_destroyNoteEditor();
|
||||
},
|
||||
saveState() {
|
||||
const listView = document.getElementById('notesListView');
|
||||
const editorView = document.getElementById('notesEditorView');
|
||||
@@ -775,56 +917,8 @@ function _registerNotesPanel() {
|
||||
});
|
||||
}
|
||||
|
||||
/** @deprecated — listeners are now wired in _registerNotesPanel() */
|
||||
function _initNotesListeners() {
|
||||
document.getElementById('notesBtn')?.addEventListener('click', openNotes);
|
||||
document.getElementById('notesNewBtn')?.addEventListener('click', () => openNoteEditor(null));
|
||||
document.getElementById('notesGraphBtn')?.addEventListener('click', () => {
|
||||
if (typeof openNoteGraph === 'function') openNoteGraph();
|
||||
});
|
||||
document.getElementById('notesTodayBtn')?.addEventListener('click', openDailyNote);
|
||||
document.getElementById('notesSelectModeBtn')?.addEventListener('click', () => {
|
||||
if (_notesSelectMode) _exitSelectMode();
|
||||
else _enterSelectMode();
|
||||
});
|
||||
document.getElementById('notesBackBtn')?.addEventListener('click', () => { showNotesList(); loadNotesList(); loadNoteFolders(); });
|
||||
document.getElementById('noteSaveBtn')?.addEventListener('click', saveNote);
|
||||
document.getElementById('noteDeleteBtn')?.addEventListener('click', deleteNote);
|
||||
document.getElementById('noteDeleteBtn2')?.addEventListener('click', deleteNote);
|
||||
document.getElementById('noteEditBtn')?.addEventListener('click', _showNoteEditMode);
|
||||
document.getElementById('notePreviewBtn')?.addEventListener('click', _showNotePreview);
|
||||
document.getElementById('noteCancelEditBtn')?.addEventListener('click', () => {
|
||||
if (_currentNote) { _populateEditFields(_currentNote); _showNoteReadMode(); }
|
||||
else showNotesList();
|
||||
});
|
||||
document.getElementById('notesFolderFilter')?.addEventListener('change', (e) => {
|
||||
document.getElementById('notesSearchInput').value = '';
|
||||
_exitSelectMode();
|
||||
loadNotesList(e.target.value);
|
||||
});
|
||||
document.getElementById('notesSortSelect')?.addEventListener('change', (e) => {
|
||||
_notesSort = e.target.value;
|
||||
_exitSelectMode();
|
||||
loadNotesList();
|
||||
});
|
||||
document.getElementById('notesSelectAll')?.addEventListener('change', (e) => {
|
||||
_toggleSelectAll(e.target.checked);
|
||||
});
|
||||
document.getElementById('notesDeleteSelectedBtn')?.addEventListener('click', _bulkDeleteSelected);
|
||||
document.getElementById('notesCancelSelectBtn')?.addEventListener('click', _exitSelectMode);
|
||||
|
||||
// Notes search with debounce
|
||||
let _notesSearchTimer;
|
||||
document.getElementById('notesSearchInput')?.addEventListener('input', (e) => {
|
||||
clearTimeout(_notesSearchTimer);
|
||||
const q = e.target.value.trim();
|
||||
_notesSearchTimer = setTimeout(() => {
|
||||
_exitSelectMode();
|
||||
if (q.length >= 2) {
|
||||
document.getElementById('notesFolderFilter').value = '';
|
||||
loadNotesList(null, q);
|
||||
} else if (q.length === 0) {
|
||||
loadNotesList();
|
||||
}
|
||||
}, 300);
|
||||
});
|
||||
// No-op: kept for backward compatibility with app.js calling sequence.
|
||||
// All wiring moved into _registerNotesPanel().
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user