mirror of
https://github.com/gauvainboiche/ketapk.git
synced 2026-09-02 11:13:11 +02:00
109 lines
3.3 KiB
JavaScript
109 lines
3.3 KiB
JavaScript
import { t } from './i18n.js';
|
|
import { APP_VERSION } from './pkCore.js';
|
|
|
|
function getFormattedTimestamp() {
|
|
const now = new Date();
|
|
const YYYY = now.getFullYear();
|
|
const DD = String(now.getDate()).padStart(2, '0');
|
|
const MM = String(now.getMonth() + 1).padStart(2, '0');
|
|
const HH = String(now.getHours()).padStart(2, '0');
|
|
const Min = String(now.getMinutes()).padStart(2, '0');
|
|
const SS = String(now.getSeconds()).padStart(2, '0');
|
|
return `${YYYY}_${DD}_${MM}_${HH}_${Min}_${SS}`;
|
|
}
|
|
|
|
function slugify(text) {
|
|
if (!text) return '';
|
|
return text
|
|
.toString()
|
|
.trim()
|
|
.toLowerCase()
|
|
.normalize("NFD").replace(/[\u0300-\u036f]/g, "")
|
|
.replace(/[^a-z0-9]+/g, "_")
|
|
.replace(/^_+|_+$/g, "");
|
|
}
|
|
|
|
export async function exportSimulationToCSV(simulationData, patientInfo) {
|
|
if (!simulationData || !simulationData.timeline) return;
|
|
|
|
let csvContent = "\uFEFF";
|
|
|
|
// Report metadata
|
|
csvContent += `${t('csv.title')}\n`;
|
|
if (patientInfo.name) {
|
|
csvContent += `${t('patient.name_label') || 'Patient'}:,${patientInfo.name}\n`;
|
|
}
|
|
csvContent += `${t('csv.weight')}:,${patientInfo.weight}\n`;
|
|
csvContent += `${t('csv.unit')}:,${patientInfo.infusionUnit}\n`;
|
|
|
|
// Version traceability line
|
|
csvContent += `${t('csv.version') || 'Version'}:,v${APP_VERSION}\n\n`;
|
|
|
|
// Table headers
|
|
const headers = [
|
|
t('csv.col_time'),
|
|
t('csv.col_bolus'),
|
|
t('csv.col_infusion'),
|
|
t('csv.col_domino'),
|
|
t('csv.col_clements'),
|
|
t('csv.col_kamp')
|
|
];
|
|
csvContent += headers.join(",") + "\n";
|
|
|
|
// Data rows
|
|
simulationData.timeline.forEach((item, index) => {
|
|
const dominoCp = (simulationData.domino && simulationData.domino[index]) ? Math.round(simulationData.domino[index].cp) : "N/A";
|
|
const clementsCp = (simulationData.clements && simulationData.clements[index]) ? Math.round(simulationData.clements[index].cp) : "N/A";
|
|
const kampCp = (simulationData.kamp && simulationData.kamp[index]) ? Math.round(simulationData.kamp[index].cp) : "N/A";
|
|
|
|
const row = [
|
|
item.time,
|
|
item.bolusMg ? item.bolusMg : "0",
|
|
item.infusionRate !== null && item.infusionRate !== undefined ? item.infusionRate : "0",
|
|
dominoCp,
|
|
clementsCp,
|
|
kampCp
|
|
];
|
|
csvContent += row.join(",") + "\n";
|
|
});
|
|
|
|
const timestamp = getFormattedTimestamp();
|
|
const slugName = slugify(patientInfo.name);
|
|
const fileName = slugName
|
|
? `ketapk_${slugName}_${timestamp}.csv`
|
|
: `ketapk_${timestamp}.csv`;
|
|
|
|
if (window.showSaveFilePicker) {
|
|
try {
|
|
const handle = await window.showSaveFilePicker({
|
|
suggestedName: fileName,
|
|
types: [{
|
|
description: 'Fichier CSV',
|
|
accept: { 'text/csv': ['.csv'] }
|
|
}]
|
|
});
|
|
const writable = await handle.createWritable();
|
|
await writable.write(csvContent);
|
|
await writable.close();
|
|
return;
|
|
} catch (err) {
|
|
if (err.name === 'AbortError') return;
|
|
console.warn('Fallback vers Data URI :', err);
|
|
}
|
|
}
|
|
|
|
const encodedUri = "data:text/csv;charset=utf-8," + encodeURIComponent(csvContent);
|
|
const link = document.createElement("a");
|
|
link.setAttribute("href", encodedUri);
|
|
link.setAttribute("download", fileName);
|
|
link.style.display = "none";
|
|
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
|
|
setTimeout(() => {
|
|
if (document.body.contains(link)) {
|
|
document.body.removeChild(link);
|
|
}
|
|
}, 200);
|
|
} |