diff --git a/public/index.html b/public/index.html
index b234fc1..a540662 100644
--- a/public/index.html
+++ b/public/index.html
@@ -494,8 +494,7 @@
-
-
+
diff --git a/public/js/notes.js b/public/js/notes.js
index d898e2e..e044ebe 100644
--- a/public/js/notes.js
+++ b/public/js/notes.js
@@ -1,3 +1,5 @@
+import * as NotesApi from './notes/api.js';
+
// ============================================================
// NOTES — per-user personal scratchpad under Clinical Tools.
// Rich-text via the app-wide Tiptap bundle (window.Tiptap).
@@ -160,7 +162,7 @@
var body = getBody();
var isNew = _activeId == null;
try {
- window.NotesApi.saveNoteKeepalive(isNew ? null : _activeId, { title: title, body: body });
+ NotesApi.saveNoteKeepalive(isNew ? null : _activeId, { title: title, body: body });
} catch (e) {}
});
@@ -210,8 +212,8 @@
if (!listEl) return;
listEl.innerHTML = '
Loading…
';
Promise.all([
- window.NotesApi.listActive(),
- window.NotesApi.listTrash(),
+ NotesApi.listActive(),
+ NotesApi.listTrash(),
])
.then(function(results) {
var active = results[0], trash = results[1];
@@ -291,7 +293,7 @@
}
function restoreNote(id) {
- window.NotesApi.restore(id)
+ NotesApi.restore(id)
.then(function(data) {
if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Restore failed', 'error'); return; }
if (typeof showToast === 'function') showToast('Note restored', 'success');
@@ -305,7 +307,7 @@
function hardDeleteNote(id) {
if (typeof showConfirm !== 'function') return;
showConfirm('Delete forever? This cannot be undone.', function() {
- window.NotesApi.hardDelete(id)
+ NotesApi.hardDelete(id)
.then(function(data) {
if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Delete failed', 'error'); return; }
refreshList();
@@ -318,7 +320,7 @@
if (_trash.length === 0) return;
showConfirm('Empty the trash? This will permanently delete ' + _trash.length + ' note' + (_trash.length === 1 ? '' : 's') + '.',
function() {
- window.NotesApi.emptyTrash()
+ NotesApi.emptyTrash()
.then(function(data) {
if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Empty trash failed', 'error'); return; }
if (typeof showToast === 'function') showToast('Trash emptied', 'success');
@@ -439,7 +441,7 @@
_autosaveInFlight = true;
updateStatus('Saving…', 'saving');
- window.NotesApi.saveNote(isNew ? null : _activeId, { title: title, body: body })
+ NotesApi.saveNote(isNew ? null : _activeId, { title: title, body: body })
.then(function(data) {
_autosaveInFlight = false;
if (!data.success) { updateStatus(data.error || 'Save failed', 'err'); return; }
@@ -449,7 +451,7 @@
// Refresh the list so the new/updated note appears with correct
// timestamps + ordering.
- return window.NotesApi.listActive()
+ return NotesApi.listActive()
.then(function(d) {
if (d.success) _notes = d.notes || [];
var note = _notes.find(function(n) { return n.id === _activeId; });
@@ -486,7 +488,7 @@
// The user can Restore from there or Empty trash to actually erase.
var doMove = function() {
flushAutosave();
- window.NotesApi.moveToTrash(_activeId)
+ NotesApi.moveToTrash(_activeId)
.then(function(data) {
if (!data.success) { updateStatus(data.error || 'Move to trash failed', 'err'); return; }
_notes = _notes.filter(function(n) { return n.id !== _activeId; });
@@ -570,7 +572,7 @@
updateStatus('Generating note…', 'saving');
var modelEl = document.getElementById('notes-model-select');
var selectedModel = modelEl ? modelEl.value : '';
- return window.NotesApi.noteFromVoice({ transcript: resp.text, model: selectedModel || undefined })
+ return NotesApi.noteFromVoice({ transcript: resp.text, model: selectedModel || undefined })
.then(function(data) {
setRecUI('idle');
if (!data.success) { updateStatus(data.error || 'Generation failed', 'err'); return; }
diff --git a/public/js/notes/api.js b/public/js/notes/api.js
index 2509e98..0f9fe88 100644
--- a/public/js/notes/api.js
+++ b/public/js/notes/api.js
@@ -1,94 +1,77 @@
-// Shared API helpers for the classic notes script.
-(function() {
- 'use strict';
+function authHeaders() {
+ return window.getAuthHeaders ? window.getAuthHeaders() : { 'Content-Type': 'application/json' };
+}
- function authHeaders() {
- return window.getAuthHeaders ? window.getAuthHeaders() : { 'Content-Type': 'application/json' };
- }
+function json(response) {
+ return response.json().catch(function() { return {}; });
+}
- function json(response) {
- return response.json().catch(function() { return {}; });
- }
+export function listActive() {
+ return fetch('/api/notes', { headers: authHeaders(), credentials: 'include' }).then(json);
+}
- function listActive() {
- return fetch('/api/notes', { headers: authHeaders(), credentials: 'include' }).then(json);
- }
+export function listTrash() {
+ return fetch('/api/notes/trash', { headers: authHeaders(), credentials: 'include' }).then(json);
+}
- function listTrash() {
- return fetch('/api/notes/trash', { headers: authHeaders(), credentials: 'include' }).then(json);
- }
+export function saveNote(id, payload) {
+ var isNew = id == null;
+ return fetch(isNew ? '/api/notes' : '/api/notes/' + id, {
+ method: isNew ? 'POST' : 'PUT',
+ headers: authHeaders(),
+ credentials: 'include',
+ body: JSON.stringify(payload || {})
+ }).then(json);
+}
- function saveNote(id, payload) {
- var isNew = id == null;
- return fetch(isNew ? '/api/notes' : '/api/notes/' + id, {
- method: isNew ? 'POST' : 'PUT',
- headers: authHeaders(),
- credentials: 'include',
- body: JSON.stringify(payload || {})
- }).then(json);
- }
+export function saveNoteKeepalive(id, payload) {
+ var isNew = id == null;
+ return fetch(isNew ? '/api/notes' : '/api/notes/' + id, {
+ method: isNew ? 'POST' : 'PUT',
+ keepalive: true,
+ credentials: 'include',
+ headers: authHeaders(),
+ body: JSON.stringify(payload || {})
+ });
+}
- function saveNoteKeepalive(id, payload) {
- var isNew = id == null;
- return fetch(isNew ? '/api/notes' : '/api/notes/' + id, {
- method: isNew ? 'POST' : 'PUT',
- keepalive: true,
- credentials: 'include',
- headers: authHeaders(),
- body: JSON.stringify(payload || {})
- });
- }
+export function restore(id) {
+ return fetch('/api/notes/' + id + '/restore', {
+ method: 'POST',
+ credentials: 'include',
+ headers: authHeaders()
+ }).then(json);
+}
- function restore(id) {
- return fetch('/api/notes/' + id + '/restore', {
- method: 'POST',
- credentials: 'include',
- headers: authHeaders()
- }).then(json);
- }
+export function hardDelete(id) {
+ return fetch('/api/notes/' + id + '?hard=1', {
+ method: 'DELETE',
+ credentials: 'include',
+ headers: authHeaders()
+ }).then(json);
+}
- function hardDelete(id) {
- return fetch('/api/notes/' + id + '?hard=1', {
- method: 'DELETE',
- credentials: 'include',
- headers: authHeaders()
- }).then(json);
- }
+export function emptyTrash() {
+ return fetch('/api/notes/trash/empty', {
+ method: 'POST',
+ credentials: 'include',
+ headers: authHeaders()
+ }).then(json);
+}
- function emptyTrash() {
- return fetch('/api/notes/trash/empty', {
- method: 'POST',
- credentials: 'include',
- headers: authHeaders()
- }).then(json);
- }
+export function moveToTrash(id) {
+ return fetch('/api/notes/' + id, {
+ method: 'DELETE',
+ headers: authHeaders(),
+ credentials: 'include'
+ }).then(json);
+}
- function moveToTrash(id) {
- return fetch('/api/notes/' + id, {
- method: 'DELETE',
- headers: authHeaders(),
- credentials: 'include'
- }).then(json);
- }
-
- function noteFromVoice(payload) {
- return fetch('/api/notes/from-voice', {
- method: 'POST',
- credentials: 'include',
- headers: authHeaders(),
- body: JSON.stringify(payload || {})
- }).then(json);
- }
-
- window.NotesApi = {
- listActive: listActive,
- listTrash: listTrash,
- saveNote: saveNote,
- saveNoteKeepalive: saveNoteKeepalive,
- restore: restore,
- hardDelete: hardDelete,
- emptyTrash: emptyTrash,
- moveToTrash: moveToTrash,
- noteFromVoice: noteFromVoice
- };
-})();
+export function noteFromVoice(payload) {
+ return fetch('/api/notes/from-voice', {
+ method: 'POST',
+ credentials: 'include',
+ headers: authHeaders(),
+ body: JSON.stringify(payload || {})
+ }).then(json);
+}