- Helper pur treatmentsForDisplay dans js/data/models.js (miroir du Kotlin, tri STABLE : actifs d'abord, inactifs après, ordre relatif conservé dans chaque groupe) — demande : « peu discernables, à placer à la fin ». - Rendu : en-tête « Traitements inactifs » (seulement s'il en existe), cartes opacity 0.55 en plus du badge — lisibles et cliquables. - Clés i18n inactive_section FR/EN ; WEB_VERSION alignée sur 1.11.0. - 4 tests treatments-display.test.js (miroir TreatmentsDisplayTest.kt). 184 tests + E2E verts (check.sh).
91 lines
3.9 KiB
JavaScript
91 lines
3.9 KiB
JavaScript
/**
|
||
* ─────────────────────────────────────────────────────────────────────────────
|
||
* Écran Traitements (portage de `ui/screens/TreatmentsScreen.kt`).
|
||
*
|
||
* Cartes (nom, voie, dose, chips ester·modèle / Tmax / ×scale / ⏰ rappel,
|
||
* badge inactif) → tap = éditeur. ⚠️ Le chip modèle passe par modelLabelKey
|
||
* (fix #59 : un ternaire à 2 branches affichait « Estrannaise » pour WHSAH).
|
||
*
|
||
* v1.11.0 (demande utilisatrice, miroir Android) : les ACTIFS d'abord, les
|
||
* INACTIFS regroupés TOUT EN BAS sous un en-tête de section, cartes
|
||
* ATTÉNUÉES (opacity 0.55) en plus du badge — « peu discernables ».
|
||
* ─────────────────────────────────────────────────────────────────────────────
|
||
*/
|
||
|
||
import { store } from '../data/store.js';
|
||
import { modelLabelKey, routeLabelKey, treatmentFlags, treatmentsForDisplay } from '../data/models.js';
|
||
import { t } from '../util/i18n.js';
|
||
import { formatDose } from '../util/format.js';
|
||
import { el, assistChip, fab } from './components.js';
|
||
|
||
/**
|
||
* Rend l'écran Traitements.
|
||
* @param {HTMLElement} container
|
||
* @param {object} ctx { openEditor: (id:number)=>void, openNew: ()=>void }
|
||
*/
|
||
export function renderTreatments(container, ctx) {
|
||
// v1.11.0 : actifs d'abord, inactifs regroupés en bas (cf treatmentsForDisplay)
|
||
const treatments = treatmentsForDisplay(store.getTreatments());
|
||
const active = treatments.filter((tr) => tr.isActive);
|
||
const inactive = treatments.filter((tr) => !tr.isActive);
|
||
|
||
const col = el('div', {});
|
||
container.appendChild(col);
|
||
|
||
if (treatments.length === 0) {
|
||
col.appendChild(el('p', {}, t('no_data')));
|
||
}
|
||
|
||
/**
|
||
* Rend UNE carte traitement. @param {object} tr @param {boolean} dimmed
|
||
* carte inactive → opacité réduite (second signal visuel au-delà du
|
||
* badge ; reste lisible et cliquable).
|
||
*/
|
||
const renderCard = (tr, dimmed) => {
|
||
const flags = treatmentFlags(tr); // miroir des getters Kotlin
|
||
const card = el('div', {
|
||
class: 'card',
|
||
style: `cursor:pointer;${dimmed ? 'opacity:0.55;' : ''}`,
|
||
onclick: () => ctx.openEditor(tr.id),
|
||
});
|
||
|
||
const titleRow = el('div', { class: 'row' });
|
||
titleRow.appendChild(el('span', { style: 'font-weight:600;flex:1;' }, tr.name));
|
||
if (!tr.isActive) titleRow.appendChild(el('span', { class: 'small' }, t('inactive')));
|
||
card.appendChild(titleRow);
|
||
|
||
card.appendChild(el('div', { class: 'sub' },
|
||
`${t(routeLabelKey(tr.route))} · ${formatDose(tr.doseAmount)} ${tr.doseUnit}`));
|
||
|
||
const chipRow = el('div', { class: 'chip-row wrap', style: 'margin-top:6px;' });
|
||
if (flags.usesProfileModel) {
|
||
// v1.4.7 (fix #59) : label via modelLabelKey — pas de ternaire à 2 branches
|
||
chipRow.appendChild(assistChip(`${tr.esterType} · ${t(modelLabelKey(tr.pkModel))}`));
|
||
} else {
|
||
chipRow.appendChild(assistChip(`${t('pk_absorption')} ${formatDose(tr.absorptionHours)}h`));
|
||
}
|
||
if (tr.scaleFactor !== 1.0) chipRow.appendChild(assistChip(`×${tr.scaleFactor.toFixed(2)}`));
|
||
if (tr.reminderEnabled) {
|
||
const hh = String(tr.reminderHour ?? 0).padStart(2, '0');
|
||
const mm = String(tr.reminderMinute ?? 0).padStart(2, '0');
|
||
chipRow.appendChild(assistChip(`⏰ ${hh}:${mm}`));
|
||
}
|
||
card.appendChild(chipRow);
|
||
return card;
|
||
};
|
||
|
||
for (const tr of active) {
|
||
col.appendChild(renderCard(tr, false));
|
||
}
|
||
|
||
// En-tête de section SEULEMENT s'il existe des inactifs (miroir Android)
|
||
if (inactive.length > 0) {
|
||
col.appendChild(el('p', { class: 'sub', style: 'margin:14px 0 4px;' }, t('inactive_section')));
|
||
}
|
||
for (const tr of inactive) {
|
||
col.appendChild(renderCard(tr, true));
|
||
}
|
||
|
||
container.appendChild(fab(ctx.openNew));
|
||
}
|