pdf-parse (was v2, broken API): - Downgraded to v1.1.1 — default export is a function again - pdfParse is not a function error fixed WebDAV file selection (style.display bug, same cascade issue): - lh-ai-webdav-selected had inline style="display:flex" always visible - selectWebdavFile() / deselectWebdavFile() now use element.style.display - On select: browser div hides, selected indicator shows with file name + X - On deselect (X): indicator hides, browser shows again Topic context for Upload and Nextcloud tabs: - Both tabs now have optional "Topic / context" field - Sent to backend as 'topic' param to help AI focus the generated content Inline refine bar (replaces window.prompt): - Refine Body button shows/hides an amber inline input bar below generate buttons - Enter instructions, press Apply — no browser dialog, works in all contexts CSP: remove unsafe-inline from scriptSrc (security issue #2): - Converted all 26 onclick= handlers in component HTML files to data-action / data-target / data-label attributes - Added delegated click handler in app.js for copy/speak/nc-export actions - script-src now 'self' only; script-src-attr 'none' WebDAV path endpoint (security issue #5): - New POST /api/user/webdav-path (authMiddleware only, not moderator) - nextcloud.js updated to use new endpoint nodemailer: already at 6.10.1 (vulnerability fixed).
154 lines
8.5 KiB
HTML
154 lines
8.5 KiB
HTML
<div class="module-header">
|
|
<h2><i class="fas fa-hospital"></i> Hospital Course Generator</h2>
|
|
<p>Upload notes by date → AI generates organized hospital course</p>
|
|
</div>
|
|
|
|
<div class="demographics-bar">
|
|
<div class="demo-field"><label>Patient Age</label><input type="text" id="hc-age" placeholder="e.g., 3 years"></div>
|
|
<div class="demo-field"><label>Gender</label><select id="hc-gender"><option value="">Select</option><option>Male</option><option>Female</option></select></div>
|
|
<div class="demo-field"><label>PMH</label><input type="text" id="hc-pmh" placeholder="e.g., asthma, obesity"></div>
|
|
<div class="demo-field">
|
|
<label>Unit</label>
|
|
<select id="hc-setting">
|
|
<option value="floor">General Floor</option>
|
|
<option value="picu">PICU</option>
|
|
<option value="nicu">NICU</option>
|
|
<option value="psych">Psych/Behavioral</option>
|
|
</select>
|
|
</div>
|
|
<div class="demo-field"><label>LOS (days)</label><input type="number" id="hc-los" placeholder="e.g., 3" min="1"></div>
|
|
<div class="demo-field">
|
|
<label>Format</label>
|
|
<select id="hc-format">
|
|
<option value="auto">Auto (AI decides)</option>
|
|
<option value="prose">Prose Summary</option>
|
|
<option value="dayByDay">Day by Day</option>
|
|
<option value="organSystem">Organ System (ICU)</option>
|
|
</select>
|
|
</div>
|
|
<div class="demo-field demo-field-model">
|
|
<label><i class="fas fa-robot"></i> Model</label>
|
|
<select class="tab-model-select"></select>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Save/Load bar -->
|
|
<div class="save-bar-wrap">
|
|
<div class="save-bar" id="hosp-save-bar">
|
|
<div style="display:flex;align-items:center;gap:8px;flex:1;">
|
|
<i class="fas fa-tag" style="color:var(--g400);font-size:13px;"></i>
|
|
<input type="text" id="hosp-label" class="save-label-input" placeholder="Patient label (e.g. John D, Visit #42)">
|
|
</div>
|
|
<button id="btn-hosp-save" class="btn-sm btn-ghost"><i class="fas fa-floppy-disk"></i> Save</button>
|
|
<button id="btn-hosp-load" class="btn-sm btn-ghost"><i class="fas fa-folder-open"></i> Load</button>
|
|
<button id="btn-hosp-new" class="btn-sm btn-ghost" title="Clear all and start new patient" style="color:var(--red);"><i class="fas fa-rotate-left"></i> New</button>
|
|
</div>
|
|
<div id="hosp-load-popover" class="enc-load-popover hidden">
|
|
<div class="enc-load-popover-inner">
|
|
<input type="text" id="hosp-load-search" class="enc-load-search" placeholder="Search saved encounters...">
|
|
<button class="enc-pop-close btn-sm btn-ghost"><i class="fas fa-times"></i></button>
|
|
</div>
|
|
<div id="hosp-pop-list" class="enc-pop-list"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ED Note -->
|
|
<div class="card">
|
|
<div class="card-header"><h3><i class="fas fa-truck-medical"></i> ED Note (before admission)</h3></div>
|
|
<div class="note-entry">
|
|
<div class="note-meta">
|
|
<input type="date" id="hc-ed-date">
|
|
<input type="text" id="hc-ed-labs" placeholder="ED Labs (e.g., WBC 15, BMP normal...)">
|
|
</div>
|
|
<div id="hc-ed-content" class="editable-box" contenteditable="true" data-placeholder="Paste or type ED note here..."></div>
|
|
<div class="note-dictate">
|
|
<button class="btn-sm btn-ghost hc-dictate-btn" data-target="hc-ed-content"><i class="fas fa-microphone"></i> Dictate</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- H&P -->
|
|
<div class="card">
|
|
<div class="card-header"><h3><i class="fas fa-file-medical"></i> H&P (Admission Note)</h3></div>
|
|
<div class="note-entry">
|
|
<div class="note-meta">
|
|
<input type="date" id="hc-hp-date">
|
|
</div>
|
|
<div id="hc-hp-content" class="editable-box" contenteditable="true" data-placeholder="Paste or type H&P here..."></div>
|
|
<div class="note-dictate">
|
|
<button class="btn-sm btn-ghost hc-dictate-btn" data-target="hc-hp-content"><i class="fas fa-microphone"></i> Dictate</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Notes (dynamic) -->
|
|
<div id="hc-notes-container">
|
|
<div class="card note-card" data-note-index="0">
|
|
<div class="card-header">
|
|
<h3><i class="fas fa-notes-medical"></i> Progress Note #1</h3>
|
|
<button class="btn-sm btn-ghost remove-note-btn"><i class="fas fa-trash"></i></button>
|
|
</div>
|
|
<div class="note-entry">
|
|
<div class="note-meta">
|
|
<input type="date" class="note-date">
|
|
<select class="note-type">
|
|
<option value="progress-attending">Progress - Attending</option>
|
|
<option value="progress-resident">Progress - Resident</option>
|
|
<option value="progress-np">Progress - NP/PA</option>
|
|
<option value="consult">Consult Note</option>
|
|
<option value="procedure">Procedure Note</option>
|
|
<option value="discharge-summary">Discharge Summary</option>
|
|
</select>
|
|
</div>
|
|
<div class="editable-box note-content" contenteditable="true" data-placeholder="Paste or type note..."></div>
|
|
<div class="note-dictate">
|
|
<button class="btn-sm btn-ghost hc-dictate-btn" data-target-class="note-content"><i class="fas fa-microphone"></i> Dictate</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button id="hc-add-note" class="btn-sm btn-ghost" style="margin:8px 0"><i class="fas fa-plus"></i> Add Progress Note</button>
|
|
|
|
<!-- Labs -->
|
|
<div class="card">
|
|
<div class="card-header"><h3><i class="fas fa-flask"></i> Labs</h3><button id="hc-add-lab" class="btn-sm btn-ghost"><i class="fas fa-plus"></i> Add</button></div>
|
|
<div id="hc-labs-container">
|
|
<div class="lab-entry">
|
|
<input type="date" class="lab-date">
|
|
<input type="text" class="lab-values" placeholder="e.g., WBC 12.5, H/H 10.2/31, BMP: Na 138, K 3.5, BUN 11, Cr 0.5">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- AI Instructions -->
|
|
<div class="card">
|
|
<div class="card-header"><h3><i class="fas fa-comment-dots"></i> Additional Instructions (optional)</h3></div>
|
|
<input type="text" id="hc-instructions" class="full-input" placeholder="e.g., 'Focus on respiratory course', 'Patient was transferred from outside hospital'">
|
|
</div>
|
|
|
|
<div class="action-row">
|
|
<button id="hc-generate-btn" class="btn-generate btn-generate-blue"><i class="fas fa-wand-magic-sparkles"></i> Generate Hospital Course</button>
|
|
</div>
|
|
|
|
<!-- Output -->
|
|
<div id="hc-output" class="card output-card hidden">
|
|
<div class="card-header output-header">
|
|
<h3><i class="fas fa-file-medical"></i> Hospital Course</h3>
|
|
<div class="output-actions">
|
|
<span id="hc-format-tag" class="model-tag"></span>
|
|
<span id="hc-model-tag" class="model-tag"></span>
|
|
<button class="btn-sm btn-primary" data-action="copy" data-target="hc-course-text"><i class="fas fa-copy"></i> Copy</button>
|
|
<button class="btn-sm btn-ghost" data-action="speak" data-target="hc-course-text"><i class="fas fa-volume-high"></i> Read</button>
|
|
<button class="btn-sm btn-ghost" data-action="nc-export" data-target="hc-course-text" data-label="hospital-course"><i class="fas fa-cloud-arrow-up"></i></button>
|
|
</div>
|
|
</div>
|
|
<div id="hc-course-text" class="output-text" contenteditable="true"></div>
|
|
<div class="refine-bar">
|
|
<input type="text" id="hc-refine-input" class="refine-input" placeholder="Tell AI to modify or add discharge day info...">
|
|
<button class="btn-sm btn-primary" id="hc-refine-btn"><i class="fas fa-edit"></i> Refine</button>
|
|
<button class="btn-sm btn-ghost" id="hc-shorten-btn"><i class="fas fa-compress"></i> Shorter</button>
|
|
<button class="btn-sm btn-warning" id="hc-clarify-btn"><i class="fas fa-circle-question"></i> What's Missing?</button>
|
|
</div>
|
|
<div id="hc-clarify-output" class="clarify-box hidden"></div>
|
|
</div>
|