convert notes scripts to modules

This commit is contained in:
Daniel 2026-05-08 01:37:41 +02:00
parent 116bd941e1
commit 1ed1a37161
3 changed files with 80 additions and 96 deletions

View file

@ -494,8 +494,7 @@
<script defer src="/js/milestones.js"></script> <script defer src="/js/milestones.js"></script>
<script defer src="/js/peGuide.js"></script> <script defer src="/js/peGuide.js"></script>
<script defer src="/js/extensions.js"></script> <script defer src="/js/extensions.js"></script>
<script defer src="/js/notes/api.js"></script> <script type="module" src="/js/notes.js"></script>
<script defer src="/js/notes.js"></script>
<script defer src="/js/diagrams.js"></script> <script defer src="/js/diagrams.js"></script>
<script type="module" src="/js/clinicalAssistant.js"></script> <script type="module" src="/js/clinicalAssistant.js"></script>
<script defer src="/js/nextcloud.js"></script> <script defer src="/js/nextcloud.js"></script>

View file

@ -1,3 +1,5 @@
import * as NotesApi from './notes/api.js';
// ============================================================ // ============================================================
// NOTES — per-user personal scratchpad under Clinical Tools. // NOTES — per-user personal scratchpad under Clinical Tools.
// Rich-text via the app-wide Tiptap bundle (window.Tiptap). // Rich-text via the app-wide Tiptap bundle (window.Tiptap).
@ -160,7 +162,7 @@
var body = getBody(); var body = getBody();
var isNew = _activeId == null; var isNew = _activeId == null;
try { try {
window.NotesApi.saveNoteKeepalive(isNew ? null : _activeId, { title: title, body: body }); NotesApi.saveNoteKeepalive(isNew ? null : _activeId, { title: title, body: body });
} catch (e) {} } catch (e) {}
}); });
@ -210,8 +212,8 @@
if (!listEl) return; if (!listEl) return;
listEl.innerHTML = '<div class="notes-empty">Loading…</div>'; listEl.innerHTML = '<div class="notes-empty">Loading…</div>';
Promise.all([ Promise.all([
window.NotesApi.listActive(), NotesApi.listActive(),
window.NotesApi.listTrash(), NotesApi.listTrash(),
]) ])
.then(function(results) { .then(function(results) {
var active = results[0], trash = results[1]; var active = results[0], trash = results[1];
@ -291,7 +293,7 @@
} }
function restoreNote(id) { function restoreNote(id) {
window.NotesApi.restore(id) NotesApi.restore(id)
.then(function(data) { .then(function(data) {
if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Restore failed', 'error'); return; } if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Restore failed', 'error'); return; }
if (typeof showToast === 'function') showToast('Note restored', 'success'); if (typeof showToast === 'function') showToast('Note restored', 'success');
@ -305,7 +307,7 @@
function hardDeleteNote(id) { function hardDeleteNote(id) {
if (typeof showConfirm !== 'function') return; if (typeof showConfirm !== 'function') return;
showConfirm('Delete forever? This cannot be undone.', function() { showConfirm('Delete forever? This cannot be undone.', function() {
window.NotesApi.hardDelete(id) NotesApi.hardDelete(id)
.then(function(data) { .then(function(data) {
if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Delete failed', 'error'); return; } if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Delete failed', 'error'); return; }
refreshList(); refreshList();
@ -318,7 +320,7 @@
if (_trash.length === 0) return; if (_trash.length === 0) return;
showConfirm('Empty the trash? This will permanently delete ' + _trash.length + ' note' + (_trash.length === 1 ? '' : 's') + '.', showConfirm('Empty the trash? This will permanently delete ' + _trash.length + ' note' + (_trash.length === 1 ? '' : 's') + '.',
function() { function() {
window.NotesApi.emptyTrash() NotesApi.emptyTrash()
.then(function(data) { .then(function(data) {
if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Empty trash failed', 'error'); return; } if (!data.success) { if (typeof showToast === 'function') showToast(data.error || 'Empty trash failed', 'error'); return; }
if (typeof showToast === 'function') showToast('Trash emptied', 'success'); if (typeof showToast === 'function') showToast('Trash emptied', 'success');
@ -439,7 +441,7 @@
_autosaveInFlight = true; _autosaveInFlight = true;
updateStatus('Saving…', 'saving'); 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) { .then(function(data) {
_autosaveInFlight = false; _autosaveInFlight = false;
if (!data.success) { updateStatus(data.error || 'Save failed', 'err'); return; } 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 // Refresh the list so the new/updated note appears with correct
// timestamps + ordering. // timestamps + ordering.
return window.NotesApi.listActive() return NotesApi.listActive()
.then(function(d) { .then(function(d) {
if (d.success) _notes = d.notes || []; if (d.success) _notes = d.notes || [];
var note = _notes.find(function(n) { return n.id === _activeId; }); 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. // The user can Restore from there or Empty trash to actually erase.
var doMove = function() { var doMove = function() {
flushAutosave(); flushAutosave();
window.NotesApi.moveToTrash(_activeId) NotesApi.moveToTrash(_activeId)
.then(function(data) { .then(function(data) {
if (!data.success) { updateStatus(data.error || 'Move to trash failed', 'err'); return; } if (!data.success) { updateStatus(data.error || 'Move to trash failed', 'err'); return; }
_notes = _notes.filter(function(n) { return n.id !== _activeId; }); _notes = _notes.filter(function(n) { return n.id !== _activeId; });
@ -570,7 +572,7 @@
updateStatus('Generating note…', 'saving'); updateStatus('Generating note…', 'saving');
var modelEl = document.getElementById('notes-model-select'); var modelEl = document.getElementById('notes-model-select');
var selectedModel = modelEl ? modelEl.value : ''; 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) { .then(function(data) {
setRecUI('idle'); setRecUI('idle');
if (!data.success) { updateStatus(data.error || 'Generation failed', 'err'); return; } if (!data.success) { updateStatus(data.error || 'Generation failed', 'err'); return; }

View file

@ -1,94 +1,77 @@
// Shared API helpers for the classic notes script. function authHeaders() {
(function() { return window.getAuthHeaders ? window.getAuthHeaders() : { 'Content-Type': 'application/json' };
'use strict'; }
function authHeaders() { function json(response) {
return window.getAuthHeaders ? window.getAuthHeaders() : { 'Content-Type': 'application/json' }; return response.json().catch(function() { return {}; });
} }
function json(response) { export function listActive() {
return response.json().catch(function() { return {}; }); return fetch('/api/notes', { headers: authHeaders(), credentials: 'include' }).then(json);
} }
function listActive() { export function listTrash() {
return fetch('/api/notes', { headers: authHeaders(), credentials: 'include' }).then(json); return fetch('/api/notes/trash', { headers: authHeaders(), credentials: 'include' }).then(json);
} }
function listTrash() { export function saveNote(id, payload) {
return fetch('/api/notes/trash', { headers: authHeaders(), credentials: 'include' }).then(json); 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) { export function saveNoteKeepalive(id, payload) {
var isNew = id == null; var isNew = id == null;
return fetch(isNew ? '/api/notes' : '/api/notes/' + id, { return fetch(isNew ? '/api/notes' : '/api/notes/' + id, {
method: isNew ? 'POST' : 'PUT', method: isNew ? 'POST' : 'PUT',
headers: authHeaders(), keepalive: true,
credentials: 'include', credentials: 'include',
body: JSON.stringify(payload || {}) headers: authHeaders(),
}).then(json); body: JSON.stringify(payload || {})
} });
}
function saveNoteKeepalive(id, payload) { export function restore(id) {
var isNew = id == null; return fetch('/api/notes/' + id + '/restore', {
return fetch(isNew ? '/api/notes' : '/api/notes/' + id, { method: 'POST',
method: isNew ? 'POST' : 'PUT', credentials: 'include',
keepalive: true, headers: authHeaders()
credentials: 'include', }).then(json);
headers: authHeaders(), }
body: JSON.stringify(payload || {})
});
}
function restore(id) { export function hardDelete(id) {
return fetch('/api/notes/' + id + '/restore', { return fetch('/api/notes/' + id + '?hard=1', {
method: 'POST', method: 'DELETE',
credentials: 'include', credentials: 'include',
headers: authHeaders() headers: authHeaders()
}).then(json); }).then(json);
} }
function hardDelete(id) { export function emptyTrash() {
return fetch('/api/notes/' + id + '?hard=1', { return fetch('/api/notes/trash/empty', {
method: 'DELETE', method: 'POST',
credentials: 'include', credentials: 'include',
headers: authHeaders() headers: authHeaders()
}).then(json); }).then(json);
} }
function emptyTrash() { export function moveToTrash(id) {
return fetch('/api/notes/trash/empty', { return fetch('/api/notes/' + id, {
method: 'POST', method: 'DELETE',
credentials: 'include', headers: authHeaders(),
headers: authHeaders() credentials: 'include'
}).then(json); }).then(json);
} }
function moveToTrash(id) { export function noteFromVoice(payload) {
return fetch('/api/notes/' + id, { return fetch('/api/notes/from-voice', {
method: 'DELETE', method: 'POST',
headers: authHeaders(), credentials: 'include',
credentials: 'include' headers: authHeaders(),
}).then(json); body: JSON.stringify(payload || {})
} }).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
};
})();