@medicus.ai/medicus-report-pdf-generator 1.3.13 → 1.3.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +3 -3
- package/HANDOVER.md +146 -0
- package/README.md +26 -26
- package/app/i18n.config.js +20 -20
- package/app/i18n_wellbeing.config.js +20 -20
- package/app/services/localeService.js +28 -28
- package/assets/Mediclinic/css/nasco_report.css +6297 -6297
- package/assets/Mediclinic/css/nasco_report_rtl.css +851 -851
- package/assets/Mediclinic/css/style.css +33 -33
- package/assets/Mediclinic/js/js.js +112 -112
- package/assets/Mediclinic/js/raphael.js +8437 -8437
- package/assets/arabic.css +275 -275
- package/assets/charts.min.js +7 -7
- package/assets/corporate_report/css/report.css +582 -582
- package/assets/corporate_report/css/report_rtl.css +144 -144
- package/assets/corporate_report/js/js.js +14 -14
- package/assets/data/data.json +124 -124
- package/assets/data/data2.json +675 -675
- package/assets/data/pdf_data_with_history.json +1255 -1255
- package/assets/doctor-note-insight-icon.svg +11 -11
- package/assets/imc/css/style.css +61 -61
- package/assets/jquery-1.4.min.js +151 -151
- package/assets/jquery-2.1.0.min.js +3 -3
- package/assets/js.js +201 -201
- package/assets/medicus_pdf/arabic.css +444 -444
- package/assets/medicus_pdf/styles.css +2427 -2427
- package/assets/print.css +4 -4
- package/assets/qr-code-style.css +68 -68
- package/assets/qrcode.min.js +3 -3
- package/assets/raphael-min.js +10 -10
- package/assets/sanusx/css/sanusx_report.css +707 -707
- package/assets/sizing.js +2 -2
- package/assets/styles.css +1545 -1545
- package/assets/styles.min.css +1358 -1358
- package/assets/translation.js +30 -30
- package/assets/wellbeing/css/nasco_report.css +3472 -3472
- package/assets/wellbeing/css/nasco_report_rtl.css +679 -679
- package/assets/wellbeing/js/js.js +111 -111
- package/assets/wellbeing/js/raphael.js +8437 -8437
- package/base64/cairo-font.js +2 -2
- package/config/Mediclinic.json +37 -37
- package/config/Najeeb.ai.json +35 -35
- package/config/Pha.json +64 -64
- package/config/bionext.json +37 -37
- package/config/default.json +35 -35
- package/config/diagnostikare.json +34 -34
- package/config/maisonsante.json +39 -39
- package/config/nasco.json +35 -35
- package/config/sanitas.json +35 -35
- package/config/sanusx.json +34 -34
- package/config/test.txt +4 -4
- package/data converter.js +53 -53
- package/docs/01-architecture-overview.md +149 -0
- package/docs/02-configuration-and-whitelabelling.md +111 -0
- package/docs/03-templating-and-rendering.md +71 -0
- package/docs/04-report-pipelines.md +128 -0
- package/docs/05-questions-and-data-model.md +67 -0
- package/docs/06-internationalization.md +59 -0
- package/docs/07-email-notifications.md +59 -0
- package/docs/08-known-issues-and-technical-debt.md +41 -0
- package/docs/README.md +22 -0
- package/downloadfile.js +6 -6
- package/example.txt +1188 -1188
- package/index.js +481 -480
- package/lib/big_integral_questionnaire.js +370 -298
- package/lib/corporate_report_generator.js +399 -399
- package/lib/pdf_generator.min.js +525 -525
- package/lib/sanusx_report_generator.js +533 -533
- package/lib/sendEmail.js +343 -343
- package/lib/template.js +2227 -2227
- package/lib/wellbeing_report_generator.js +2164 -2134
- package/locales/ar-AE.json +169 -169
- package/locales/ar-SA.json +169 -169
- package/locales/ar.json +397 -397
- package/locales/de.json +169 -169
- package/locales/en.json +229 -229
- package/locales/fr.json +168 -168
- package/locales/pt.json +165 -165
- package/locales/wellbeing/ar-AE.json +149 -149
- package/locales/wellbeing/ar-SA.json +257 -257
- package/locales/wellbeing/de.json +301 -301
- package/locales/wellbeing/en.json +423 -423
- package/locales/wellbeing/es.json +133 -133
- package/locales/wellbeing/fr.json +121 -121
- package/locales/wellbeing/it-IT.json +121 -121
- package/locales/wellbeing/pt.json +121 -121
- package/locales/wellbeing/tr.json +121 -121
- package/locales/wellbeing/zh-CN.json +121 -121
- package/locales/zh-CN.json +165 -165
- package/package.json +47 -47
- package/preview-big-integral.js +75 -75
- package/run.js +15 -15
- package/templates/Mediclinic/blocks/first-section.html +205 -205
- package/templates/Mediclinic/blocks/footer.html +7 -7
- package/templates/Mediclinic/blocks/header-template.html +5 -5
- package/templates/Mediclinic/blocks/header.html +20 -20
- package/templates/Mediclinic/blocks/patient-table.html +38 -38
- package/templates/Mediclinic/blocks/pdf-header.html +9 -9
- package/templates/Mediclinic/blocks/tips.html +8 -8
- package/templates/Mediclinic/ltr_no_pages.html +37 -37
- package/templates/Mediclinic/rtl_no_pages.html +42 -42
- package/templates/Mediclinic/wellbeing_template.html +41 -41
- package/templates/Pha/blocks/first-section.html +207 -207
- package/templates/Pha/blocks/footer.html +7 -7
- package/templates/Pha/blocks/header-template.html +5 -5
- package/templates/Pha/blocks/header.html +20 -20
- package/templates/Pha/blocks/patient-table.html +38 -38
- package/templates/Pha/blocks/pdf-header.html +8 -8
- package/templates/Pha/blocks/tips.html +8 -8
- package/templates/Pha/ltr_no_pages.html +37 -37
- package/templates/Pha/rtl_no_pages.html +42 -42
- package/templates/Pha/wellbeing_template.html +41 -41
- package/templates/base.html +23 -23
- package/templates/blocks/ar-first-page-header.html +68 -68
- package/templates/blocks/ar-footer.html +54 -54
- package/templates/blocks/ar-header.html +67 -67
- package/templates/blocks/biomarker-compact-ar.html +27 -27
- package/templates/blocks/biomarker-compact.html +27 -27
- package/templates/blocks/biomarker-details.html +41 -41
- package/templates/blocks/biomarker-insight.html +22 -22
- package/templates/blocks/biomarker-min.html +9 -9
- package/templates/blocks/doctor-note.html +11 -11
- package/templates/blocks/footer.html +35 -35
- package/templates/blocks/header-first-page.html +46 -46
- package/templates/blocks/header.html +49 -49
- package/templates/blocks/panel-compact.html +38 -38
- package/templates/blocks/panel-details.html +16 -16
- package/templates/blocks/report-summary.html +16 -16
- package/templates/blocks/section-title.html +4 -4
- package/templates/blocks/signature.html +16 -16
- package/templates/blocks/summary-insight.html +15 -15
- package/templates/blocks/summary.html +9 -9
- package/templates/corporate_report/cover_page.html +23 -23
- package/templates/corporate_report/footer.html +9 -9
- package/templates/corporate_report/ltr_no_pages.html +20 -20
- package/templates/corporate_report/page.html +24 -24
- package/templates/corporate_report/participant_analytics.html +5 -5
- package/templates/corporate_report/rtl_no_pages.html +20 -20
- package/templates/empty.html +10 -10
- package/templates/first_page_head.html +157 -157
- package/templates/imc/first-header-template.html +53 -53
- package/templates/ltr.html +1368 -1368
- package/templates/ltr_no_pages.html +89 -89
- package/templates/maisonsante/blocks/first-section.html +151 -207
- package/templates/maisonsante/blocks/footer.html +7 -7
- package/templates/maisonsante/blocks/header-template.html +5 -5
- package/templates/maisonsante/blocks/header.html +20 -20
- package/templates/maisonsante/blocks/patient-table.html +38 -38
- package/templates/maisonsante/blocks/pdf-header.html +8 -8
- package/templates/maisonsante/blocks/tips.html +8 -8
- package/templates/maisonsante/ltr_no_pages.html +38 -38
- package/templates/maisonsante/rtl_no_pages.html +43 -43
- package/templates/maisonsante/wellbeing_template.html +41 -41
- package/templates/no_pages.html +1224 -1224
- package/templates/popup/popup-template.html +129 -129
- package/templates/rtl_no_pages.html +92 -92
- package/templates/sanusx/blocks/footer.html +6 -6
- package/templates/sanusx/blocks/header.html +20 -20
- package/templates/sanusx/blocks/personal-details.html +123 -123
- package/templates/sanusx/blocks/predictions-section.html +57 -57
- package/templates/sanusx/blocks/recommendations-section.html +6 -6
- package/templates/sanusx/blocks/super-power-section.html +29 -29
- package/templates/sanusx/blocks/tips.html +8 -8
- package/templates/sanusx/ltr_no_pages.html +26 -26
- package/templates/sanusx/rtl_no_pages.html +36 -36
- package/templates/template.html +1377 -1377
- package/templates/wellbeing/blocks/first-section.html +106 -106
- package/templates/wellbeing/blocks/footer.html +7 -7
- package/templates/wellbeing/blocks/header.html +37 -37
- package/templates/wellbeing/blocks/tips.html +8 -8
- package/templates/wellbeing/ltr_no_pages.html +35 -35
- package/templates/wellbeing/rtl_no_pages.html +36 -36
- package/templates/wellbeing/wellbeing_template.html +43 -43
- package/test.js +74 -74
- package/testing-reports/mediclinic/arabic-data.js +0 -439
- package/testing-reports/mediclinic/doctor-data.js +0 -523
- package/testing-reports/mediclinic/with-wellbeing.js +0 -415
- package/testing-reports/pha/notes-example.js +0 -397
package/lib/template.js
CHANGED
|
@@ -1,2227 +1,2227 @@
|
|
|
1
|
-
const LocaleService = require('../app/services/localeService.js');
|
|
2
|
-
const i18n = require('../app/i18n_wellbeing.config.js');
|
|
3
|
-
fetchFileContents
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
let useMonospace = false;
|
|
8
|
-
function setUseMonospace(val) { useMonospace = val; }
|
|
9
|
-
const INDENTATION = {
|
|
10
|
-
PANEL_TITLE: 12,
|
|
11
|
-
BIOMARKER_DETAILS: 12,
|
|
12
|
-
INSIGHT: 12,
|
|
13
|
-
PAGE_WIDTH: 794
|
|
14
|
-
};
|
|
15
|
-
var localeService = new LocaleService(i18n);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function renderHTMLTemplate(html, isRtl, data, isIMCLab, lang = 'en') {
|
|
19
|
-
let dir = isRtl ? 'rtl' : 'ltr';
|
|
20
|
-
let language = isRtl ? 'ar' : 'en';
|
|
21
|
-
let IMCclass = isIMCLab ? 'imc-lab' : '';
|
|
22
|
-
let styles = fetchFileContents(path.resolve(__dirname, '../assets/medicus_pdf/styles.css'));
|
|
23
|
-
if (isRtl) {
|
|
24
|
-
styles += fetchFileContents(path.resolve(__dirname, '../assets/medicus_pdf/arabic.css'));
|
|
25
|
-
}
|
|
26
|
-
let bodyClass = "";
|
|
27
|
-
if (!data['approvalDate']) {
|
|
28
|
-
bodyClass = "draft-bg";
|
|
29
|
-
if (lang !== 'en' && ['ar', 'de', 'fr', 'nl-NL', 'pt', 'pt_BR', 'ar-SA'].includes(lang)) {
|
|
30
|
-
|
|
31
|
-
bodyClass = "draft-bg-" + lang;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (data['labType'] === 18) {
|
|
35
|
-
bodyClass += ' smart-donor';
|
|
36
|
-
}
|
|
37
|
-
const fs = require('fs');
|
|
38
|
-
let content = `
|
|
39
|
-
<div>
|
|
40
|
-
<div id="page_template" class="all-pages ${IMCclass}">
|
|
41
|
-
|
|
42
|
-
${html}
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
`;
|
|
46
|
-
|
|
47
|
-
return content;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function returnIntroTemplate(data, isIMCLab) {
|
|
51
|
-
let profileItemHTML = '';
|
|
52
|
-
let classProfileItemContainer = "size4";
|
|
53
|
-
let widthProfileItemContainer = '';
|
|
54
|
-
let introWidth = '';
|
|
55
|
-
if (isIMCLab || (!process.env.SHOW_QR_BOX || process.env.SHOW_QR_BOX === "false")) {
|
|
56
|
-
classProfileItemContainer = '';
|
|
57
|
-
widthProfileItemContainer = 'width:100%';
|
|
58
|
-
introWidth = 'width:100%';
|
|
59
|
-
|
|
60
|
-
let length = 100 / 3;
|
|
61
|
-
let items = data['profileItems'];
|
|
62
|
-
if (data['reportProperties'] && isIMCLab) {
|
|
63
|
-
for (const [key, value] of Object.entries(data['reportProperties'])) {
|
|
64
|
-
items.push({title: key, value: value});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
for (const item of items) {
|
|
69
|
-
profileItemHTML += `<div style='width: ${length}%; padding: 10px 0' class='grid-col size2'>
|
|
70
|
-
<div class='info-label'>${item.title}</div>
|
|
71
|
-
<div class='info-value'>${item.value}</div>
|
|
72
|
-
</div>`;
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
let index = 0;
|
|
76
|
-
while (index < data['profileItems'].length - 1) {
|
|
77
|
-
let newDivId = 'sub' + index;
|
|
78
|
-
profileItemHTML += `<div id="${newDivId}" class='grid-row'>`;
|
|
79
|
-
|
|
80
|
-
for (let j = 0; j < 2; j++) {
|
|
81
|
-
let valueId = newDivId + '-' + j;
|
|
82
|
-
let profileItemValue = data['profileItems'][index]['value'];
|
|
83
|
-
let classAttr = /[A-Za-z]/.test(profileItemValue) && /[0-9]/.test(profileItemValue) ? "ltr_dir" : "";
|
|
84
|
-
|
|
85
|
-
profileItemHTML += `<div id='${valueId}' class='grid-col size2'>
|
|
86
|
-
<div class='info-label'>${data['profileItems'][index]['title']}</div>
|
|
87
|
-
<div class='info-value ${classAttr}'>${profileItemValue}</div>
|
|
88
|
-
</div>`;
|
|
89
|
-
index++;
|
|
90
|
-
}
|
|
91
|
-
profileItemHTML += `</div>`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (data['profileItems'].length % 2 !== 0) {
|
|
95
|
-
let newDivId = 'sub' + index;
|
|
96
|
-
let valueId = newDivId + '-0';
|
|
97
|
-
let profileItemValue = data['profileItems'][index]['value'];
|
|
98
|
-
let classAttr = /[A-Za-z]/.test(profileItemValue) && /[0-9]/.test(profileItemValue) ? "ltr_dir" : "";
|
|
99
|
-
|
|
100
|
-
profileItemHTML += `<div id="${newDivId}" class='grid-row'>
|
|
101
|
-
<div id='${valueId}' class='grid-col size2'>
|
|
102
|
-
<div class='info-label'>${data['profileItems'][index]['title']}</div>
|
|
103
|
-
<div class='info-value ${classAttr}'>${profileItemValue}</div>
|
|
104
|
-
</div>
|
|
105
|
-
</div>`;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
let moreLink = localeService.t('Access your detailed report online') + " ";
|
|
110
|
-
moreLink = moreLink.replace("{link}", `<strong><a href='${data['moreLink']}' target='_blank'>${data['moreLink']}</a></strong>`);
|
|
111
|
-
|
|
112
|
-
if (data['patientPin'] && data['showPIN'] && data['qrCode']) {
|
|
113
|
-
moreLink += localeService.t("Scan this report’s QR code or enter this PIN code:") + "";
|
|
114
|
-
} else if (data['patientPin'] && data['showPIN']) {
|
|
115
|
-
moreLink += localeService.t("Enter this PIN code:") + "";
|
|
116
|
-
} else if (data['qrCode']) {
|
|
117
|
-
moreLink += localeService.t("Scan this report’s QR code:") + "";
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
let content = '';
|
|
121
|
-
let pin = data['patientPin'] || '';
|
|
122
|
-
let qrImage = data['qrCode'] || '';
|
|
123
|
-
let displayPin = pin ? 'inline-block' : 'none';
|
|
124
|
-
let displayQR = qrImage ? 'inline-block' : 'none';
|
|
125
|
-
let reportTitle = data['labType'] === 18 ? 'Smart Report' : localeService.t('Smart Report');
|
|
126
|
-
|
|
127
|
-
content += `<div class="intro" style="${introWidth}">
|
|
128
|
-
<div class="grid-row">
|
|
129
|
-
<div class="profile-items-container grid-col ${classProfileItemContainer}" style="${widthProfileItemContainer}">
|
|
130
|
-
<div id="report-title-header-ltr" class="report-title">
|
|
131
|
-
<div class="heading">${reportTitle}</div>
|
|
132
|
-
</div>
|
|
133
|
-
<div id="patient-container">${profileItemHTML}</div>
|
|
134
|
-
</div>`;
|
|
135
|
-
|
|
136
|
-
if (!isIMCLab && (process.env.SHOW_QR_BOX === "true" || process.env.SHOW_QR_BOX === true) && data['labType'] !== 18) {
|
|
137
|
-
content += `<div class="plus-info-container grid-col size4">
|
|
138
|
-
<div class="plus-info">
|
|
139
|
-
<div class="grid-row">
|
|
140
|
-
<div class="grid-col size3">
|
|
141
|
-
<div id="more-link" class="description">${moreLink}
|
|
142
|
-
<span id="pin" class="pin" style="display:${displayPin}">${pin}</span>
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
<div class="grid-col size1 qr-container">
|
|
146
|
-
<div id="qrcode" class="pin-qr" style="display:${displayQR}"><img src="${qrImage}"></div>
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
149
|
-
</div>
|
|
150
|
-
</div>`;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
content += '</div></div>';
|
|
154
|
-
|
|
155
|
-
return content;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
function renderDoctorNotes(doctorNotes, bioIndentStyle = '') {
|
|
160
|
-
let doctorNotesHTML = '';
|
|
161
|
-
if (doctorNotes && doctorNotes.length > 0) {
|
|
162
|
-
doctorNotes.forEach(note => {
|
|
163
|
-
let noteId = 'doctor-note-' + Math.random().toString(36).substr(2, 9);
|
|
164
|
-
doctorNotesHTML += `<div class="card-wrapper card-wrapper-note" style="${bioIndentStyle}">
|
|
165
|
-
<div id="${noteId}" class="card">
|
|
166
|
-
<div class="icon">
|
|
167
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
168
|
-
<g fill="none" fill-rule="evenodd">
|
|
169
|
-
<rect width="32" height="32" fill="" rx="16"/>
|
|
170
|
-
<g fill="#295C42" fill-rule="nonzero">
|
|
171
|
-
<path d="M20.613 23.8a.31.31 0 0 0 .217-.088l1.845-1.8a.296.296 0 0 0 .09-.212v-12c0-.166-.137-.3-.307-.3h-1.845a.304.304 0 0 0-.308.3c0 .166.138.3.308.3h1.537v11.576l-1.755 1.712a.295.295 0 0 0 0 .424.31.31 0 0 0 .218.088z"/>
|
|
172
|
-
<path d="M11.387 10c.17 0 .308-.134.308-.3 0-.166-.138-.3-.308-.3H9.542a.304.304 0 0 0-.307.3v12.9c0 .662.552 1.2 1.23 1.2h8.918c.17 0 .307-.134.307-.3v-1.8c0-.136.137-.3.308-.3h1.23c.17 0 .307-.134.307-.3 0-.166-.137-.3-.307-.3h-1.23c-.492 0-.923.42-.923.9v1.5h-8.61a.608.608 0 0 1-.615-.6V10h1.537zM16 8.2c-.34 0-.615.27-.615.6 0 .33.276.6.615.6.34 0 .615-.27.615-.6 0-.33-.276-.6-.615-.6z"/>
|
|
173
|
-
<path d="M22.458 8.2h-1.845a.304.304 0 0 0-.308.3c0 .166.138.3.308.3h1.845c.448 0 .922.463.922.9v13.8c0 .437-.474.9-.922.9H9.542c-.448 0-.922-.463-.922-.9V9.7c0-.437.474-.9.922-.9h1.845c.17 0 .308-.134.308-.3 0-.166-.138-.3-.308-.3H9.542c-.79 0-1.537.729-1.537 1.5v13.8c0 .771.747 1.5 1.537 1.5h12.916c.79 0 1.537-.729 1.537-1.5V9.7c0-.771-.747-1.5-1.537-1.5z"/>
|
|
174
|
-
</g>
|
|
175
|
-
</g>
|
|
176
|
-
</svg>
|
|
177
|
-
</div>
|
|
178
|
-
<div class="text text-with-icon">
|
|
179
|
-
<div class="from-doctor">${localeService.t('noteFromDoctor')} ${note.createdByName}</div>
|
|
180
|
-
<div class="note-content">${note.content.replace(/\n/g, "<br/>")}</div>
|
|
181
|
-
</div>
|
|
182
|
-
</div>
|
|
183
|
-
</div>`;
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
return doctorNotesHTML;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function renderDoctorNotesCompactView(doctorNotes, bioIndentStyle = '') {
|
|
190
|
-
let doctorNotesHTML = '';
|
|
191
|
-
if (doctorNotes && doctorNotes.length > 0) {
|
|
192
|
-
doctorNotes.forEach(note => {
|
|
193
|
-
doctorNotesHTML += `<div class="note-content">${note.content}</div>`;
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
return doctorNotesHTML;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function renderOneBiomarker(biomarker, isRtl, nestingLevel, isChildBiomarker, isComponent) {
|
|
200
|
-
|
|
201
|
-
let biomarkerDetailsHtml = '';
|
|
202
|
-
|
|
203
|
-
if (biomarker.showInDetailsView === true) {
|
|
204
|
-
const biomarkerCssId = "dtl-bio-" + "db" + biomarker.id;
|
|
205
|
-
let customBiomarkerValueFontSize = '';
|
|
206
|
-
const rawFormattedValue = biomarker.formattedValue || biomarker.lingualReading || '';
|
|
207
|
-
const formattedValue = rawFormattedValue.replace(/,/g, "");
|
|
208
|
-
if (formattedValue.length > 35) {
|
|
209
|
-
customBiomarkerValueFontSize = 'font-size:12px;';
|
|
210
|
-
}
|
|
211
|
-
const biomarkerName = biomarker.name || '';
|
|
212
|
-
const biomarkerStatus = biomarker.status || '';
|
|
213
|
-
const insightsCount = biomarker.insightsCount || '';
|
|
214
|
-
let CircleStyles = '';
|
|
215
|
-
if (!isComponent) {
|
|
216
|
-
CircleStyles = GetBiomarkerCircleStyle(biomarker.color, biomarkerName, biomarkerStatus, insightsCount, '', false);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Indent biomarker details based on panel level
|
|
220
|
-
let firstGridColClass = 'size5';
|
|
221
|
-
let firstGridColstyle = '';
|
|
222
|
-
let lastGridColClass = 'size3';
|
|
223
|
-
let bioIndentStyle = '';
|
|
224
|
-
let bioIndentNoteStyle = '';
|
|
225
|
-
if (nestingLevel > 0) {
|
|
226
|
-
// Replace classes
|
|
227
|
-
firstGridColClass = 'size5';
|
|
228
|
-
lastGridColClass = 'size3';
|
|
229
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
230
|
-
const levelNesting = extraPadding + nestingLevel * (INDENTATION.BIOMARKER_DETAILS || 0);
|
|
231
|
-
const levelNestingNote = extraPadding + nestingLevel * (INDENTATION.BIOMARKER_DETAILS || 0) + 16;
|
|
232
|
-
bioIndentStyle = 'padding-left: ' + levelNesting + 'px;';
|
|
233
|
-
bioIndentNoteStyle = 'padding-left: ' + levelNestingNote + 'px';
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// IMC special case (large biomarker value)
|
|
237
|
-
let biomarkerClass = '';
|
|
238
|
-
if (rawFormattedValue.length >= 125) {
|
|
239
|
-
biomarkerClass = 'large-value-class';
|
|
240
|
-
firstGridColClass = '';
|
|
241
|
-
// firstGridColstyle = 'width:100%';
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const biomarkerValue = rawFormattedValue.replace(/\r\n/g, "<br/>");
|
|
245
|
-
|
|
246
|
-
if (!biomarker.showScale) {
|
|
247
|
-
biomarkerClass += ' hide-scale ';
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const biomarkerColor = (biomarker.color && !biomarker.isNormal) ? "color:" + biomarker.color + ";" : "";
|
|
251
|
-
let rangesPlaceholder = "";
|
|
252
|
-
let currentRange = "";
|
|
253
|
-
let currentPercent = 50;
|
|
254
|
-
let biomarkerTitleClass = '';
|
|
255
|
-
if (biomarker.ranges.length > 1 && biomarker.showScale) {
|
|
256
|
-
biomarkerTitleClass = 'has-ranges';
|
|
257
|
-
} else {
|
|
258
|
-
biomarkerTitleClass = 'has-no-ranges';
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
let childRangesPlaceholder = "";
|
|
262
|
-
let childCurrentRange = "";
|
|
263
|
-
let heightCount = 1;
|
|
264
|
-
let bioValue = "";
|
|
265
|
-
let bioUnit = "";
|
|
266
|
-
let afterBioInfoValue = '';
|
|
267
|
-
let History = '';
|
|
268
|
-
if (biomarker.childrenBiomarkers && biomarker.childrenBiomarkers.length > 0) {
|
|
269
|
-
biomarker.childrenBiomarkers.forEach(bio => {
|
|
270
|
-
if (bio.ranges.length > 1) {
|
|
271
|
-
heightCount++;
|
|
272
|
-
// Viewing the biomarker and unit of children after the parent ones
|
|
273
|
-
bioValue = bio.formattedValue.replace(/\n/g, "<br />");
|
|
274
|
-
let bioValue_style = "";
|
|
275
|
-
if (bioValue.length > 33) {
|
|
276
|
-
bioValue_style = "font-size:12px;";
|
|
277
|
-
}
|
|
278
|
-
bioUnit = bio.unit;
|
|
279
|
-
childCurrentRange = '';
|
|
280
|
-
// Generating the children ranges and display them under the parent ones
|
|
281
|
-
childRangesPlaceholder += '<div class="extra-range-placeholder">'
|
|
282
|
-
+ convertToRangeLayout(bio.ranges, bio, isRtl)
|
|
283
|
-
+ '</div>';
|
|
284
|
-
biomarkerTitleClass = 'has-ranges';
|
|
285
|
-
afterBioInfoValue += '<div class="colorable pair">'
|
|
286
|
-
+ '<span class="biomarker-extra-value" style="' + bioValue_style + '">' + bioValue + '</span>'
|
|
287
|
-
+ '<span class="biomarker-extra-unit">' + bioUnit + '</span>'
|
|
288
|
-
+ '</div>';
|
|
289
|
-
} else {
|
|
290
|
-
biomarkerTitleClass = 'has-no-ranges';
|
|
291
|
-
}
|
|
292
|
-
History = renderBiomarkerHistoryChart(bio);
|
|
293
|
-
});
|
|
294
|
-
} else {
|
|
295
|
-
History = renderBiomarkerHistoryChart(biomarker);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (heightCount > 1) {
|
|
299
|
-
biomarkerClass += 'hide-flag';
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Set biomarker history chart
|
|
303
|
-
const biomarkerFullName = biomarker.fullName || '';
|
|
304
|
-
let bioName = biomarkerFullName.replace(/\r\n/g, '');
|
|
305
|
-
bioName = bioName.replace(/\n/g, '');
|
|
306
|
-
const rangePlaceHolder = convertToRangeLayout(biomarker.ranges, biomarker, isRtl);
|
|
307
|
-
let biomarkerSampleHTML = '';
|
|
308
|
-
let biomInfoStyle = '';
|
|
309
|
-
let biomValueAlignStyle = '';
|
|
310
|
-
if (biomarker.sample) {
|
|
311
|
-
biomarkerSampleHTML += '<div class="biom-sample">'
|
|
312
|
-
+ '<span class="biom-sample-value">'
|
|
313
|
-
+ biomarker.sample
|
|
314
|
-
+ '</span>'
|
|
315
|
-
+ '</div>';
|
|
316
|
-
// biomValueAlignStyle = "vertical-align: bottom;";
|
|
317
|
-
}
|
|
318
|
-
if (!biomarker.sample && (rangePlaceHolder || childRangesPlaceholder || History)) {
|
|
319
|
-
biomInfoStyle = "margin-top:15px;";
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Configurations
|
|
323
|
-
let biomarkerScale = '';
|
|
324
|
-
if (isChildBiomarker) {
|
|
325
|
-
// biomarkerScale = 'transform:scale(.9);';
|
|
326
|
-
}
|
|
327
|
-
let biomCircleCss = '';
|
|
328
|
-
if (isComponent) {
|
|
329
|
-
biomCircleCss = 'opacity: 0;';
|
|
330
|
-
biomarkerSampleHTML = '';
|
|
331
|
-
bioName = '';
|
|
332
|
-
}
|
|
333
|
-
let panelNesting = '';
|
|
334
|
-
let biomarkerTitleWidth = 'width:260px';
|
|
335
|
-
if (nestingLevel > 0) {
|
|
336
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
337
|
-
const levelNesting = extraPadding + nestingLevel * (INDENTATION.PANEL_TITLE || 0);
|
|
338
|
-
panelNesting = 'padding-left: ' + levelNesting + 'px;box-sizing:border-box;';
|
|
339
|
-
const width = 260 - levelNesting;
|
|
340
|
-
biomarkerTitleWidth = 'width:' + width + 'px';
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if ((!rangePlaceHolder || !biomarker.showScale) && !childRangesPlaceholder && !History) {
|
|
344
|
-
biomarkerScale += 'width:100%;';
|
|
345
|
-
}
|
|
346
|
-
const doctorNotesArr = biomarker.doctorNotes || [];
|
|
347
|
-
const doctorNotes = renderDoctorNotes(doctorNotesArr, bioIndentNoteStyle);
|
|
348
|
-
let bioNameStyle = '';
|
|
349
|
-
let isValueNumber = !isNaN(Number(biomarkerValue));
|
|
350
|
-
let valueDataType = isValueNumber ? "number" : "string";
|
|
351
|
-
const safeBioName = bioName
|
|
352
|
-
.replace(/\(/g, '(')
|
|
353
|
-
.replace(/\)/g, ')');
|
|
354
|
-
biomarkerDetailsHtml += '<div data-id="' + biomarkerCssId + '" class="biomarker-container grid-col ' + biomarkerClass + '">'
|
|
355
|
-
+ '<div class="grid-col ' + firstGridColClass + ' ' + biomarkerClass + '" style="' + biomarkerScale + panelNesting + '">'
|
|
356
|
-
+ '<div class="biomarker">'
|
|
357
|
-
+ '<div class="biom-circle" style="' + removeWhiteSpace(CircleStyles) + ';' + biomCircleCss + '">' + biomarkerName + '</div>'
|
|
358
|
-
+ '<div class="biom-info ' + biomarkerTitleClass + '" style="' + biomInfoStyle + '">'
|
|
359
|
-
+ '<div class="title ' + biomarkerTitleClass + '" style="' + biomarkerTitleWidth + '">' + biomarkerSampleHTML + '<span class="bio-name-info b" dir="ltr" style="unicode-bidi:isolate;">' + safeBioName + '</span></div>'
|
|
360
|
-
+ '<div class="value colorable" style="' + biomValueAlignStyle + '">'
|
|
361
|
-
+ biomarkerSampleHTML
|
|
362
|
-
+ '<div class="pair parent-pair">'
|
|
363
|
-
+ '<span class="value-text" data-type="' + valueDataType + '">'
|
|
364
|
-
+ '<span style="' + customBiomarkerValueFontSize + biomarkerColor + '">' + biomarkerValue + '</span>'
|
|
365
|
-
+ '</span>'
|
|
366
|
-
+ '<span dir="ltr" class="unit colorable">' + biomarker.unit + '</span>'
|
|
367
|
-
+ '</div>'
|
|
368
|
-
+ '</div>'
|
|
369
|
-
+ afterBioInfoValue
|
|
370
|
-
+ '</div>'
|
|
371
|
-
+ '</div>'
|
|
372
|
-
+ '</div>';
|
|
373
|
-
|
|
374
|
-
if (rangePlaceHolder || childRangesPlaceholder || History) {
|
|
375
|
-
biomarkerDetailsHtml += '<div class="grid-col ' + lastGridColClass + ' ' + biomarkerClass + '" style="' + biomarkerScale + '">';
|
|
376
|
-
let biomBarClass = "";
|
|
377
|
-
if (biomarker.ranges.length > 6) {
|
|
378
|
-
biomBarClass = "big";
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
biomarkerDetailsHtml += '<div class="biom-bar ' + biomBarClass + '">';
|
|
382
|
-
}
|
|
383
|
-
if (rangePlaceHolder && biomarker.showScale) {
|
|
384
|
-
biomarkerDetailsHtml += '<div class="range-placeholder c">' + convertToRangeLayout(biomarker.ranges, biomarker, isRtl) + '</div>';
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if (childRangesPlaceholder) {
|
|
388
|
-
biomarkerDetailsHtml += childRangesPlaceholder;
|
|
389
|
-
}
|
|
390
|
-
if (rangePlaceHolder || childRangesPlaceholder || History) {
|
|
391
|
-
biomarkerDetailsHtml += '</div><!-- close biom-bar -->';
|
|
392
|
-
// History chart start
|
|
393
|
-
biomarkerDetailsHtml += '<div class="grid-col history-chart-col">';
|
|
394
|
-
|
|
395
|
-
if (History) {
|
|
396
|
-
biomarkerDetailsHtml += '<div class="chart">'
|
|
397
|
-
+ History
|
|
398
|
-
+ '</div>';
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
biomarkerDetailsHtml += '</div> <!-- end chart grid col -->';
|
|
402
|
-
// History chart end
|
|
403
|
-
biomarkerDetailsHtml += '</div> <!-- close last grid-col -->';
|
|
404
|
-
}
|
|
405
|
-
if (doctorNotes) {
|
|
406
|
-
biomarkerDetailsHtml += '<div class="grid-row biomarker-insights b">'
|
|
407
|
-
+ doctorNotes
|
|
408
|
-
+ '</div>';
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
biomarkerDetailsHtml += '</div> <!-- end first close biomarker-container-->';
|
|
412
|
-
}
|
|
413
|
-
return biomarkerDetailsHtml;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
function renderBiomarkerDetails(panel, isRtl, counter) {
|
|
417
|
-
let content = '';
|
|
418
|
-
panel.biomarkers.forEach((biomarker, biomarkrCounter) => {
|
|
419
|
-
content += renderOneBiomarker(biomarker, biomarkrCounter, panel, isRtl, counter);
|
|
420
|
-
});
|
|
421
|
-
return content;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
function renderPanelTitle(panel, counter, biomarkrCounter) {
|
|
425
|
-
let panelTitle = '';
|
|
426
|
-
let panelSubTitle = '';
|
|
427
|
-
let content = '';
|
|
428
|
-
let checkShowInDetailsView = panel.biomarkers.find(biomarker => biomarker.showInDetailsView === true);
|
|
429
|
-
|
|
430
|
-
if (panel.biomarkers && checkShowInDetailsView && biomarkrCounter === 0) {
|
|
431
|
-
if (panel.panelDetails && panel.panelDetails.length > 1) {
|
|
432
|
-
panelTitle = panel.panelDetails[0].name;
|
|
433
|
-
let newPanelDetails = panel.panelDetails;
|
|
434
|
-
|
|
435
|
-
if (newPanelDetails.length > 0) {
|
|
436
|
-
newPanelDetails.forEach((panelDetail, index) => {
|
|
437
|
-
if (index > 0) {
|
|
438
|
-
let marginLeft = (index + 1) * 10;
|
|
439
|
-
let name = panelDetail.name ? panelDetail.name : '';
|
|
440
|
-
panelSubTitle += `<div class="panel-subtitle-item" style="padding-left:${marginLeft}px">${name}</div>`;
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
} else {
|
|
445
|
-
panelTitle = panel.panelDetails && panel.panelDetails[0] && panel.panelDetails[0].name ? panel.panelDetails[0].name : panel.name;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
let detailsTitle = '';
|
|
449
|
-
if (counter === 0) {
|
|
450
|
-
detailsTitle = `<div id="details-section" class="section">
|
|
451
|
-
<div class="resume-title">${localeService.t('Details')}</div>
|
|
452
|
-
</div>`;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
content += `${detailsTitle}
|
|
456
|
-
<div class="panel-title">${panelTitle}</div>
|
|
457
|
-
<div class="panel-subtitle">${panelSubTitle}</div>`;
|
|
458
|
-
}
|
|
459
|
-
return content;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
function renderPanelDetails(panel, biomarkerDetailsHtml, counter, isRtl) {
|
|
463
|
-
const panelCssId = `dtl-pnl-dp${panel.panelId.toLowerCase()}`;
|
|
464
|
-
const checkShowInDetailsView = panel.biomarkers.find(biomarker => biomarker.showInDetailsView === true);
|
|
465
|
-
let detailsSectionHTML = '';
|
|
466
|
-
let panelSubTitle = '';
|
|
467
|
-
|
|
468
|
-
if (panel.biomarkers && checkShowInDetailsView) {
|
|
469
|
-
let panelTitle = panel.panelDetails && panel.panelDetails.length > 1 ? panel.panelDetails[0].name : panel.name;
|
|
470
|
-
|
|
471
|
-
if (panel.panelDetails && panel.panelDetails.length > 1) {
|
|
472
|
-
panel.panelDetails.forEach((panelDetail, index) => {
|
|
473
|
-
if (index > 0) {
|
|
474
|
-
let marginLeft = (index + 1) * 10;
|
|
475
|
-
let name = panelDetail.name ? panelDetail.name : '';
|
|
476
|
-
panelSubTitle += `<div class="panel-subtitle-item" style="padding-left:${marginLeft}px">${name}</div>`;
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
let detailsTitle = '';
|
|
482
|
-
if (counter === 0) {
|
|
483
|
-
detailsTitle = `<div id="details-section" class="section">
|
|
484
|
-
<div class="resume-title">${localeService.t('Details')}</div>
|
|
485
|
-
</div>`;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
let panelInsights = renderRelatedInsights(panel.insights, panel, true, `dtl-pnl-insight-${panel.panelId}`, isRtl);
|
|
489
|
-
let doctorNotes = renderDoctorNotes(panel.doctorNotes);
|
|
490
|
-
let bioInsights = (doctorNotes || panelInsights) ? `<div class="grid-row biomarker-insights">${doctorNotes}${panelInsights}</div>` : '';
|
|
491
|
-
|
|
492
|
-
detailsSectionHTML += `<div id="${panelCssId}" class="section panel sectionPanel">
|
|
493
|
-
<div class="panel-wrapper">
|
|
494
|
-
<div class="section-content">
|
|
495
|
-
<div class="panel-container">${biomarkerDetailsHtml}</div>
|
|
496
|
-
${bioInsights}
|
|
497
|
-
</div>
|
|
498
|
-
</div>
|
|
499
|
-
</div>`;
|
|
500
|
-
}
|
|
501
|
-
return detailsSectionHTML;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
function renderOneInsight(insight, nestingLevel, isRtl) {
|
|
505
|
-
const INDENTATION = {INSIGHT: 10}; // Assuming this is defined globally
|
|
506
|
-
let insightHtml = '';
|
|
507
|
-
const insightCssId = "insight-" + "cb" + insight.id + Math.floor(Math.random() * 3);
|
|
508
|
-
let insightClass = "";
|
|
509
|
-
let content = '';
|
|
510
|
-
let tolerance = "";
|
|
511
|
-
let introductoryStatement = "";
|
|
512
|
-
let nodes = "";
|
|
513
|
-
let doctorContentClass = "hide-me";
|
|
514
|
-
let insightImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAAEgCAMAAAAjXV6yAAAAdVBMVEUAAACAma+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama/V/8ZIAAAAJnRSTlMATE389dtK6SQE7uTUOc/HlysO3qeJbwnBf1kzaBwWuZ+zYEJ1UwEot4sAAATfSURBVHja7NprcqpAEIbhDwckclPu4iUajb3/JZ78MDWQ1CmhKtKN9LOEt2bGGWwopZRSSimllFJKKaWUUkoppZRSSimllFJKKfVCFs+2vMZxelxhohx6NuMGfh4lp80trTE9Do3G5MnZecfEODQqNyqW01pHDo0tWB+OmA6HxmeSz+nsNIc4mOQwlY3mEA/3tMckOMQlbzJMgENs3I83yGcDbZxn2VXNeRv59EuyhHg20AJPlcXVh2eoKzxAuhECWWm1dqnDb6Q/0kYJZNW7bTdRUEK2kQJZ9SGiNreUvYZGC2QdC5dagk9IxhAIdelTi7+DYByBgItHLZ7kSzVPINx8alkLft4zBcI+IssUcg9qrkBYhGQFco8htkCoArISsZuML9CqdMk6S91kfIGQbckKY8jEGAjXkKwPoUuIMxA2ZPlCP32wBkpzsk4ylxBrIGzkn0K8gWKfrDMk4g304ZEVyD2G2AKhCshKxG4yvkCr0iXrLHWT8QVCtiUrjCETYyBcQ7I+hC4hzkDYkOUL/fTBGijNyTrJXEKsgbCRfwrxBop9ss6QiDfQh0dWIPcYYguEKiArEbvJ+AKtSpess9RNxhcI2ZasMIZMjIFwDcn6ELqEOANhQ5Yv9NMHa6A0J+skcwmxBsJG/inEGyj2yTpDIt5AHx5ZgdxjiC0QqoCsROwm4wu0Kl2yzlI3GV8gZFuywhgyMQbCNSTrQ+gS4gyEDVm+0E8frIHSnKyTzCXEGggb+acQb6DYJ+sMiXgDfXhkBXKPIbZAqAKyErGbjC/QqnTJOkvdZHyBkG3JCmPIxBgI15CsD6FLiDMQNmT5Qj99sAZKc7JOMpcQayBs5J9CvIFin6wzJOIN9OGRFcg9htgCoQrISsRuMr5Aq9Il6yx1k/EFQrYlK4whE2MgXEOyPoQuIc5A2JDlC/30wRoozck6yVxCrIGwkX8K8QaKfbLOkIg30IdHViD3GGILhCogKxG7yfgCrUqXrLPUTcYXCNmWrDCGTIyBcA3J+hC6hDgDYUOWL/TTB2ugNCfrJHMJsQbCRv4pxBso9sk6QyLeQB8eWYHcY4gtEKqArETsJuMLtCpdss5SNxlfIGRbssIYMjEGwjUk60PoEuIMhA1ZvtBPH6yB0pysk8wlxBoIG/mnEG+g2CfrDIl4A314ZAVyjyG2QKgCshKxm4wv0Kp0yTpL3WR8gZBtyQpjyMQYCNeQrA+hS4gzEDZk+UI/fbAGSnOyTjKXEGsgbOSfQryBYp+sMyTiDfThkRXIPYbYAqEKyErEbjK+QKvSJessdZPxBUK2JSuMIRNjIFxDsj6ELiHOQNiQ5Qv99MEaKM3JOsn+3yX0DgAAAAAAAAAAAPi3Dx06cIqm05GlAAAAAElFTkSuQmCC";
|
|
515
|
-
let insightTextClass = "";
|
|
516
|
-
let relatedBiomarkers = "";
|
|
517
|
-
|
|
518
|
-
if (insight.title) {
|
|
519
|
-
content += `<div class='title'>${insight.title}</div>`;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
if (insight.introductoryStatement) {
|
|
523
|
-
introductoryStatement = insight.introductoryStatement + " ";
|
|
524
|
-
} else {
|
|
525
|
-
introductoryStatement = insight.content;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
let insightCssIdStyle = '';
|
|
529
|
-
if (nestingLevel > 0) {
|
|
530
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1)
|
|
531
|
-
const levelNesting = extraPadding + nestingLevel * INDENTATION.INSIGHT;
|
|
532
|
-
insightCssIdStyle = `padding-left: ${levelNesting}px`;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
function renderOneInsight(insight, nestingLevel, isRtl) {
|
|
536
|
-
const INDENTATION = {INSIGHT: 10}; // Assuming this is defined globally
|
|
537
|
-
let insightHtml = '';
|
|
538
|
-
const insightCssId = "insight-" + "cb" + insight.id.toLowerCase() + Math.floor(Math.random() * 3);
|
|
539
|
-
let insightClass = "";
|
|
540
|
-
let content = '';
|
|
541
|
-
let tolerance = "";
|
|
542
|
-
let introductoryStatement = "";
|
|
543
|
-
let nodes = "";
|
|
544
|
-
let doctorContentClass = "hide-me";
|
|
545
|
-
let insightImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAAEgCAMAAAAjXV6yAAAAdVBMVEUAAACAma+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama/V/8ZIAAAAJnRSTlMATE389dtK6SQE7uTUOc/HlysO3qeJbwnBf1kzaBwWuZ+zYEJ1UwEot4sAAATfSURBVHja7NprcqpAEIbhDwckclPu4iUajb3/JZ78MDWQ1CmhKtKN9LOEt2bGGWwopZRSSimllFJKKaWUUkoppZRSSimllFJKKfVCFs+2vMZxelxhohx6NuMGfh4lp80trTE9Do3G5MnZecfEODQqNyqW01pHDo0tWB+OmA6HxmeSz+nsNIc4mOQwlY3mEA/3tMckOMQlbzJMgENs3I83yGcDbZxn2VXNeRv59EuyhHg20AJPlcXVh2eoKzxAuhECWWm1dqnDb6Q/0kYJZNW7bTdRUEK2kQJZ9SGiNreUvYZGC2QdC5dagk9IxhAIdelTi7+DYByBgItHLZ7kSzVPINx8alkLft4zBcI+IssUcg9qrkBYhGQFco8htkCoArISsZuML9CqdMk6S91kfIGQbckKY8jEGAjXkKwPoUuIMxA2ZPlCP32wBkpzsk4ylxBrIGzkn0K8gWKfrDMk4g304ZEVyD2G2AKhCshKxG4yvkCr0iXrLHWT8QVCtiUrjCETYyBcQ7I+hC4hzkDYkOUL/fTBGijNyTrJXEKsgbCRfwrxBop9ss6QiDfQh0dWIPcYYguEKiArEbvJ+AKtSpess9RNxhcI2ZasMIZMjIFwDcn6ELqEOANhQ5Yv9NMHa6A0J+skcwmxBsJG/inEGyj2yTpDIt5AHx5ZgdxjiC0QqoCsROwm4wu0Kl2yzlI3GV8gZFuywhgyMQbCNSTrQ+gS4gyEDVm+0E8frIHSnKyTzCXEGggb+acQb6DYJ+sMiXgDfXhkBXKPIbZAqAKyErGbjC/QqnTJOkvdZHyBkG3JCmPIxBgI15CsD6FLiDMQNmT5Qj99sAZKc7JOMpcQayBs5J9CvIFin6wzJOIN9OGRFcg9htgCoQrISsRuMr5Aq9Il6yx1k/EFQrYlK4whE2MgXEOyPoQuIc5A2JDlC/30wRoozck6yVxCrIGwkX8K8QaKfbLOkIg30IdHViD3GGILhCogKxG7yfgCrUqXrLPUTcYXCNmWrDCGTIyBcA3J+hC6hDgDYUOWL/TTB2ugNCfrJHMJsQbCRv4pxBso9sk6QyLeQB8eWYHcY4gtEKqArETsJuMLtCpdss5SNxlfIGRbssIYMjEGwjUk60PoEuIMhA1ZvtBPH6yB0pysk8wlxBoIG/mnEG+g2CfrDIl4A314ZAVyjyG2QKgCshKxm4wv0Kp0yTpL3WR8gZBtyQpjyMQYCNeQrA+hS4gzEDZk+UI/fbAGSnOyTjKXEGsgbOSfQryBYp+sMyTiDfThkRXIPYbYAqEKyErEbjK+QKvSJessdZPxBUK2JSuMIRNjIFxDsj6ELiHOQNiQ5Qv99MEaKM3JOsn+3yX0DgAAAAAAAAAAAPi3Dx06cIqm05GlAAAAAElFTkSuQmCC";
|
|
546
|
-
let insightTextClass = "";
|
|
547
|
-
let relatedBiomarkers = "";
|
|
548
|
-
|
|
549
|
-
if (insight.title) {
|
|
550
|
-
content += `<div class='title'>${insight.title}</div>`;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
if (insight.introductoryStatement) {
|
|
554
|
-
introductoryStatement = insight.introductoryStatement + " ";
|
|
555
|
-
} else {
|
|
556
|
-
introductoryStatement = insight.content;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
let insightCssIdStyle = '';
|
|
560
|
-
if (nestingLevel > 0) {
|
|
561
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1)
|
|
562
|
-
const levelNesting = extraPadding + nestingLevel * INDENTATION.INSIGHT;
|
|
563
|
-
insightCssIdStyle = `padding-left: ${levelNesting}px`;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
if (insight.introductoryStatement || insight.summary || insight.testExplained || insight.suggestion) {
|
|
567
|
-
const introductoryStatementContent = introductoryStatement ? introductoryStatement.replace(/(\r\n|\n|\r)/gm, '') : '';
|
|
568
|
-
const insightSummaryContent = insight.summary ? insight.summary : '';
|
|
569
|
-
const testExplainedContent = insight.testExplained ? insight.testExplained : '';
|
|
570
|
-
const suggestionContent = insight.suggestion ? insight.suggestion : '';
|
|
571
|
-
content += `<div class="html-content inline-text introductory-statement">${introductoryStatementContent}</div>`;
|
|
572
|
-
content += `<div class="html-content inline-text testExplained">${testExplainedContent}</div>`;
|
|
573
|
-
content += `<div class="html-content inline-text">${insightSummaryContent}</div>`;
|
|
574
|
-
content += `<div class="html-content">${suggestionContent}</div>`;
|
|
575
|
-
|
|
576
|
-
if (isRtl) {
|
|
577
|
-
content = content.replace(/‏/g, '');
|
|
578
|
-
content = content.replace(/\(/g, '‏ <span class="ltr-dir">(');
|
|
579
|
-
content = content.replace(/\)/g, ') ‏</span>');
|
|
580
|
-
}
|
|
581
|
-
} else {
|
|
582
|
-
content += introductoryStatement;
|
|
583
|
-
if (isRtl) {
|
|
584
|
-
content = content.replace(/‏/g, '');
|
|
585
|
-
content = content.replace(/\(/g, '‏ <span class="ltr-dir">(');
|
|
586
|
-
content = content.replace(/\)/g, ') ‏</span>');
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
if (insight.detailedList) {
|
|
591
|
-
const parsedTable = parseTable(insight.detailedList);
|
|
592
|
-
nodes = renderDetails(parsedTable, isRtl);
|
|
593
|
-
doctorContentClass = "";
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
if (introductoryStatement) {
|
|
597
|
-
const span = "<span>";
|
|
598
|
-
if (introductoryStatement.includes(span)) {
|
|
599
|
-
tolerance = stripTags(introductoryStatement, '<span>');
|
|
600
|
-
introductoryStatement = introductoryStatement.replace(/<(.|\n)*?>/g, '');
|
|
601
|
-
introductoryStatement = introductoryStatement.replace(tolerance, '');
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (insight.color === "") {
|
|
606
|
-
insightClass = "tip";
|
|
607
|
-
} else {
|
|
608
|
-
insightClass = color(insight.color);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// if (insight.icon !== "") {
|
|
612
|
-
// insightImage = getFileAsBase64(insight.icon, 'image/png');
|
|
613
|
-
// }
|
|
614
|
-
|
|
615
|
-
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
616
|
-
insightTextClass = "insight-text";
|
|
617
|
-
// Loop through relatedBiomarkers and generate HTML (commented out in PHP)
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
let insightCssIdCss = '';
|
|
621
|
-
if (nestingLevel > 0) {
|
|
622
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1)
|
|
623
|
-
const levelNesting = extraPadding + nestingLevel * INDENTATION.INSIGHT + 16;
|
|
624
|
-
insightCssIdCss = `padding-left: ${levelNesting}px`;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
let svgColor = color(insight.color);
|
|
628
|
-
if (insight.isMedical) {
|
|
629
|
-
insightClass += ' medical-insight';
|
|
630
|
-
svgColor = ' medical-insight';
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
if (content || insight.disclaimer || insight.toleranceText) {
|
|
634
|
-
insightHtml += `<div id="${insightCssId}" class="card-wrapper" style="${insightCssIdCss}" insight-id="${insight.id}">
|
|
635
|
-
<div class="card insight-card a ${insightClass}">
|
|
636
|
-
<div class="insight-container">`;
|
|
637
|
-
if (insight.isMedical || insight.insightType === 'doctor-visit') {
|
|
638
|
-
insightHtml += `<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 52 52" fill="none" class="card-svg ${svgColor}">
|
|
639
|
-
<path d="M17 0C15.8955 0 15 0.895447 15 2V15H2C0.895508 15 0 15.8954 0 17V35C0 36.1046 0.895508 37 2 37H15V50C15 51.1046 15.8955 52 17 52H35C36.1045 52 37 51.1046 37 50V37H50C51.1045 37 52 36.1046 52 35V17C52 15.8954 51.1045 15 50 15H37V2C37 0.895416 36.1045 0 35 0H17Z" fill="white"/>
|
|
640
|
-
</svg>`;
|
|
641
|
-
}
|
|
642
|
-
insightHtml += `<div class="text ${insightTextClass}">${content}</div>`;
|
|
643
|
-
|
|
644
|
-
if (insight.disclaimer) {
|
|
645
|
-
insightHtml += `<div class="insight-disclaimer" style="padding: 10px 0px 0">${insight.disclaimer}</div>`;
|
|
646
|
-
}
|
|
647
|
-
if (insight.toleranceText) {
|
|
648
|
-
insightHtml += `<div class="insight-tolerance" style="padding: 10px 0px 0">${insight.toleranceText}</div>`;
|
|
649
|
-
}
|
|
650
|
-
insightHtml += `</div>`;
|
|
651
|
-
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
652
|
-
insightHtml += `<div id="${insightCssId}" class="related-icons has-related ${color(insight.color)}">${relatedBiomarkers}</div>`;
|
|
653
|
-
}
|
|
654
|
-
insightHtml += `</div></div>`;
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
if (nodes || tolerance) {
|
|
658
|
-
insightHtml += `<div class="card-wrapper detailed-list-card-wrapper" style="${insightCssIdCss}">
|
|
659
|
-
<div class="detailed-list-wrapper">
|
|
660
|
-
<div class="detailed-list-title-wrapper">
|
|
661
|
-
<div class="doctor-only-content-container ${doctorContentClass}">
|
|
662
|
-
<h4 class="doctor-only-content-header">${getLocale('doctorContent')}</h4>
|
|
663
|
-
<span class="doctor-only-content-subheader">${getLocale('mostCommonCausesOfTheObservedValue')}</span>
|
|
664
|
-
</div>`;
|
|
665
|
-
if (nodes) {
|
|
666
|
-
insightHtml += `<ul class="detailed-list">${nodes}</ul>`;
|
|
667
|
-
}
|
|
668
|
-
if (tolerance) {
|
|
669
|
-
insightHtml += `<div class="tolerance-text">${tolerance}</div>`;
|
|
670
|
-
}
|
|
671
|
-
insightHtml += `</div></div></div>`;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
return insightHtml;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
if (insight.introductoryStatement || insight.summary || insight.testExplained || insight.suggestion) {
|
|
678
|
-
const introductoryStatementContent = introductoryStatement ? introductoryStatement.replace(/(\r\n|\n|\r)/gm, '') : '';
|
|
679
|
-
const insightSummaryContent = insight.summary ? insight.summary : '';
|
|
680
|
-
const testExplainedContent = insight.testExplained ? insight.testExplained : '';
|
|
681
|
-
const suggestionContent = insight.suggestion ? insight.suggestion : '';
|
|
682
|
-
content += `<div class="html-content inline-text introductory-statement">${introductoryStatementContent}</div>`;
|
|
683
|
-
content += `<div class="html-content inline-text testExplained">${testExplainedContent}</div>`;
|
|
684
|
-
content += `<div class="html-content inline-text">${insightSummaryContent}</div>`;
|
|
685
|
-
content += `<div class="html-content">${suggestionContent}</div>`;
|
|
686
|
-
|
|
687
|
-
if (isRtl) {
|
|
688
|
-
content = content.replace(/‏/g, '');
|
|
689
|
-
content = content.replace(/\(/g, '‏ <span class="ltr-dir">(');
|
|
690
|
-
content = content.replace(/\)/g, ') ‏</span>');
|
|
691
|
-
}
|
|
692
|
-
} else {
|
|
693
|
-
content += introductoryStatement;
|
|
694
|
-
if (isRtl) {
|
|
695
|
-
content = content.replace(/‏/g, '');
|
|
696
|
-
content = content.replace(/\(/g, '‏ <span class="ltr-dir">(');
|
|
697
|
-
content = content.replace(/\)/g, ') ‏</span>');
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
if (insight.detailedList) {
|
|
702
|
-
const parsedTable = parseTable(insight.detailedList);
|
|
703
|
-
nodes = renderDetails(parsedTable, isRtl);
|
|
704
|
-
doctorContentClass = "";
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
if (introductoryStatement) {
|
|
708
|
-
const span = "<span>";
|
|
709
|
-
if (introductoryStatement.includes(span)) {
|
|
710
|
-
tolerance = stripTags(introductoryStatement, '<span>');
|
|
711
|
-
introductoryStatement = introductoryStatement.replace(/<(.|\n)*?>/g, '');
|
|
712
|
-
introductoryStatement = introductoryStatement.replace(tolerance, '');
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
if (insight.color === "") {
|
|
717
|
-
insightClass = "tip";
|
|
718
|
-
} else {
|
|
719
|
-
insightClass = color(insight.color);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
// if (insight.icon !== "") {
|
|
723
|
-
// insightImage = getFileAsBase64(insight.icon, 'image/png');
|
|
724
|
-
// }
|
|
725
|
-
|
|
726
|
-
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
727
|
-
insightTextClass = "insight-text";
|
|
728
|
-
// Loop through relatedBiomarkers and generate HTML (commented out in PHP)
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
let insightCssIdCss = '';
|
|
732
|
-
if (nestingLevel > 0) {
|
|
733
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1)
|
|
734
|
-
const levelNesting = extraPadding + nestingLevel * INDENTATION.INSIGHT + 16;
|
|
735
|
-
insightCssIdCss = `padding-left: ${levelNesting}px`;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
let svgColor = color(insight.color);
|
|
739
|
-
if (insight.isMedical) {
|
|
740
|
-
insightClass += ' medical-insight';
|
|
741
|
-
svgColor = ' medical-insight';
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
if (content || insight.disclaimer || insight.toleranceText) {
|
|
745
|
-
insightHtml += `<div id="${insightCssId}" class="card-wrapper" style="${insightCssIdCss}" insight-id="${insight.id}">
|
|
746
|
-
<div class="card insight-card a ${insightClass}">
|
|
747
|
-
<div class="insight-container">`;
|
|
748
|
-
if (insight.isMedical || insight.insightType === 'doctor-visit') {
|
|
749
|
-
insightHtml += `<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 52 52" fill="none" class="card-svg ${svgColor}">
|
|
750
|
-
<path d="M17 0C15.8955 0 15 0.895447 15 2V15H2C0.895508 15 0 15.8954 0 17V35C0 36.1046 0.895508 37 2 37H15V50C15 51.1046 15.8955 52 17 52H35C36.1045 52 37 51.1046 37 50V37H50C51.1045 37 52 36.1046 52 35V17C52 15.8954 51.1045 15 50 15H37V2C37 0.895416 36.1045 0 35 0H17Z" fill="white"/>
|
|
751
|
-
</svg>`;
|
|
752
|
-
}
|
|
753
|
-
insightHtml += `<div class="text ${insightTextClass}">${content}</div>`;
|
|
754
|
-
|
|
755
|
-
if (insight.disclaimer) {
|
|
756
|
-
insightHtml += `<div class="insight-disclaimer" style="padding: 10px 0px 0">${insight.disclaimer}</div>`;
|
|
757
|
-
}
|
|
758
|
-
if (insight.toleranceText) {
|
|
759
|
-
insightHtml += `<div class="insight-tolerance" style="padding: 10px 0px 0">${insight.toleranceText}</div>`;
|
|
760
|
-
}
|
|
761
|
-
insightHtml += `</div>`;
|
|
762
|
-
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
763
|
-
insightHtml += `<div id="${insightCssId}" class="related-icons has-related ${color(insight.color)}">${relatedBiomarkers}</div>`;
|
|
764
|
-
}
|
|
765
|
-
insightHtml += `</div></div>`;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
if (nodes || tolerance) {
|
|
769
|
-
insightHtml += `<div class="card-wrapper detailed-list-card-wrapper" style="${insightCssIdCss}">
|
|
770
|
-
<div class="detailed-list-wrapper">
|
|
771
|
-
<div class="detailed-list-title-wrapper">
|
|
772
|
-
<div class="doctor-only-content-container ${doctorContentClass}">
|
|
773
|
-
<h4 class="doctor-only-content-header">${getLocale('doctorContent')}</h4>
|
|
774
|
-
<span class="doctor-only-content-subheader">${getLocale('mostCommonCausesOfTheObservedValue')}</span>
|
|
775
|
-
</div>`;
|
|
776
|
-
if (nodes) {
|
|
777
|
-
insightHtml += `<ul class="detailed-list">${nodes}</ul>`;
|
|
778
|
-
}
|
|
779
|
-
if (tolerance) {
|
|
780
|
-
insightHtml += `<div class="tolerance-text">${tolerance}</div>`;
|
|
781
|
-
}
|
|
782
|
-
insightHtml += `</div></div></div>`;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
return insightHtml;
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
function renderRelatedInsights(insights, panel, showRelatedBiomarkers = true, idPrefix = '', isRtl = false) {
|
|
789
|
-
let content = '';
|
|
790
|
-
if (insights.length > 0) {
|
|
791
|
-
insights.forEach((insight, insightIndex) => {
|
|
792
|
-
content += renderOneInsight(insight, insightIndex, idPrefix, panel, showRelatedBiomarkers, isRtl);
|
|
793
|
-
});
|
|
794
|
-
}
|
|
795
|
-
return content;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
function setSummaryStatInsightText(summary) {
|
|
799
|
-
let insightsHasStackedArray = [];
|
|
800
|
-
let temp2 = [...summary];
|
|
801
|
-
|
|
802
|
-
summary.forEach((summaryCheckedItem, index) => {
|
|
803
|
-
if (summaryCheckedItem.stackedInsight !== null) {
|
|
804
|
-
let test = {};
|
|
805
|
-
|
|
806
|
-
temp2.forEach((stackedElement, i) => {
|
|
807
|
-
if (stackedElement && stackedElement.id === summaryCheckedItem.stackedInsight) {
|
|
808
|
-
test.index = i;
|
|
809
|
-
summaryCheckedItem.content += `<br><br>${stackedElement.content}`;
|
|
810
|
-
test.elm = summaryCheckedItem;
|
|
811
|
-
insightsHasStackedArray[index] = stackedElement;
|
|
812
|
-
summary[test.index] = test.elm;
|
|
813
|
-
summary.splice(i, 1);
|
|
814
|
-
}
|
|
815
|
-
});
|
|
816
|
-
}
|
|
817
|
-
});
|
|
818
|
-
return summary;
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
function returnSummaryTemplate(summaryI, isRtl) {
|
|
822
|
-
let summary = setSummaryStatInsightText(summaryI);
|
|
823
|
-
let insightIndex = 0;
|
|
824
|
-
let insightHtml = '';
|
|
825
|
-
|
|
826
|
-
summary.forEach(insight => {
|
|
827
|
-
let insightCssId = `smry-insight${insightIndex}`;
|
|
828
|
-
let relatedBiomarkers = '';
|
|
829
|
-
let insightCssClass = insight.isClinicalReading ? "cr" : insight.color === "" ? "tip" : color(insight.color);
|
|
830
|
-
|
|
831
|
-
let insightText = insight.title ? `<div class="title">${insight.title}</div>` : '';
|
|
832
|
-
let insightContent = insight.content;
|
|
833
|
-
|
|
834
|
-
if (isRtl) {
|
|
835
|
-
insightContent = insightContent.replace(/‏/g, '')
|
|
836
|
-
.replace(/\(/g, '‏ <span class="ltr-dir">(')
|
|
837
|
-
.replace(/\)/g, ') ‏</span>');
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
insightText += insightContent.replace(/(\r\n|\n|\r)/gm, '<br/>');
|
|
841
|
-
|
|
842
|
-
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
843
|
-
insight.relatedBiomarkers.forEach(item => {
|
|
844
|
-
relatedBiomarkers += GetRelatedBiomarker(
|
|
845
|
-
GetBiomarkerCircleStyle(item.color, item.name, item.status, item.insightsCount, 'nothing', true, item),
|
|
846
|
-
item.name,
|
|
847
|
-
item.fullName
|
|
848
|
-
);
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
let svgColor = color(insight.color);
|
|
853
|
-
if (insight.isMedical) {
|
|
854
|
-
insightCssClass += ' medical-insight';
|
|
855
|
-
svgColor = ' medical-insight';
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
insightHtml += `<div id="${insightCssId}" class="card insight-card ${insightCssClass}">
|
|
859
|
-
<div class="insight-container">
|
|
860
|
-
<div class="text">${insightText}</div>
|
|
861
|
-
${insight.toleranceText ? `<div class="text" style="color: #FF3200; padding: 10px 0px 5px 0px;">${insight.toleranceText}</div>` : ''}
|
|
862
|
-
</div>
|
|
863
|
-
${insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0 ? `<div id="${insightCssId}" class="related-icons has-related ${color(insight.color)}">${relatedBiomarkers}</div>` : ''}
|
|
864
|
-
</div>`;
|
|
865
|
-
|
|
866
|
-
insightIndex++;
|
|
867
|
-
});
|
|
868
|
-
return insightHtml;
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
function renderSummary(data, isRtl) {
|
|
872
|
-
let content = '';
|
|
873
|
-
let reportNotes = '';
|
|
874
|
-
let summary = '';
|
|
875
|
-
|
|
876
|
-
if ((data.summary) || (data.doctorNote && data.doctorNote.length > 0)) {
|
|
877
|
-
if (data.doctorNote && data.doctorNote.length > 0) {
|
|
878
|
-
reportNotes = renderDoctorNotes(data.doctorNote);
|
|
879
|
-
}
|
|
880
|
-
if (data.summary) {
|
|
881
|
-
summary = returnSummaryTemplate(data.summary, isRtl);
|
|
882
|
-
}
|
|
883
|
-
if (reportNotes && summary)
|
|
884
|
-
content += `
|
|
885
|
-
<div id="summary" class="section">
|
|
886
|
-
<div class="resume-title">${localeService.t('Summary')}</div>
|
|
887
|
-
<div class="section-content report-notes">${reportNotes}${summary}</div>
|
|
888
|
-
</div>
|
|
889
|
-
`;
|
|
890
|
-
}
|
|
891
|
-
return content;
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
function renderReportSummary(data, isIMCLab) {
|
|
895
|
-
let content = '';
|
|
896
|
-
if (data.reportSummary || (data.reportProperties && !isIMCLab)) {
|
|
897
|
-
content += '<br/><br/>';
|
|
898
|
-
let reportProperties = '';
|
|
899
|
-
|
|
900
|
-
content += '<div id="report-summary" class="section">';
|
|
901
|
-
if (data.reportSummary) {
|
|
902
|
-
content += `
|
|
903
|
-
<div class="resume-title report-summary-title">${localeService.t('reportSummary')}</div>
|
|
904
|
-
<div class="section-content report-summary-content">${data.reportSummary}</div>
|
|
905
|
-
`;
|
|
906
|
-
}
|
|
907
|
-
/* add report properties */
|
|
908
|
-
if (data.reportProperties && !isIMCLab) {
|
|
909
|
-
for (const [key, value] of Object.entries(data.reportProperties)) {
|
|
910
|
-
reportProperties += `<p>${key}: ${value}</p>`;
|
|
911
|
-
}
|
|
912
|
-
content += `
|
|
913
|
-
<div class="resume-title report-properties-title">${localeService.t('reportProperties')}</div>
|
|
914
|
-
<div class="section-content report-properties-content">${reportProperties}</div>
|
|
915
|
-
`;
|
|
916
|
-
}
|
|
917
|
-
content += '</div>';
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
return content;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
function renderSignature(data, isRtl, isIMCLab) {
|
|
924
|
-
let content = '';
|
|
925
|
-
let textAlign = isRtl ? 'right' : 'left';
|
|
926
|
-
|
|
927
|
-
// Lab address
|
|
928
|
-
let labAddress = '';
|
|
929
|
-
if (data.labAddress && data.labType !== 18) {
|
|
930
|
-
labAddress = data.labAddress.replace(/\n/g, "<br>");
|
|
931
|
-
}
|
|
932
|
-
content += `<td style="vertical-align: middle;"><div style="padding: 0 25px;font-size: 14px;text-align: ${textAlign};line-height: 1.4;word-break: break-all;">
|
|
933
|
-
${labAddress}
|
|
934
|
-
</div></td>`;
|
|
935
|
-
|
|
936
|
-
// Lab tel, email, and site
|
|
937
|
-
let labPhone = data.labPhoneNumber ? `${localeService.t('Tel:')} ${data.labPhoneNumber}<br/>` : '';
|
|
938
|
-
let labEmail = data.labEmailAddress ? `${localeService.t('Email:')} ${data.labEmailAddress}<br/>` : '';
|
|
939
|
-
let labSite = data.moreLink ? `${data.moreLink}<br/>` : '';
|
|
940
|
-
|
|
941
|
-
if (data.labType === 18) {
|
|
942
|
-
labSite = "Web: http://www.smartdonor.it/<br/>";
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
if (labPhone || labEmail || labSite) {
|
|
946
|
-
content += `<td style="vertical-align: middle;"><div style="width: 2px; height: 100%;background:rgba(157,169,180, 0.5);min-height: 70px "> </div></td>`;
|
|
947
|
-
}
|
|
948
|
-
content += `<td style="vertical-align: middle;"><div style="padding: 0 25px;font-size: 14px;text-align: ${textAlign};line-height: 1.4;">
|
|
949
|
-
${labPhone}
|
|
950
|
-
${labEmail}
|
|
951
|
-
${labSite}
|
|
952
|
-
</div></td>`;
|
|
953
|
-
|
|
954
|
-
if (data.labType !== 18 && !isIMCLab && (data.labStamp || (data.signatures && data.signatures.length > 0))) {
|
|
955
|
-
content += `<td style="vertical-align: middle;"><div style="width: 2px; height: 100%;background:rgba(157,169,180, 0.5);min-height: 70px"> </div></td>`;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
if (data.labType !== 18 && data.signatures && data.signatures.length > 0) {
|
|
959
|
-
data.signatures.forEach((signature, index) => {
|
|
960
|
-
let approvedBy = signature.name;
|
|
961
|
-
content += `<td style="vertical-align: middle;">
|
|
962
|
-
<div class="approved-by-doctor" style="padding: 0 25px;font-size: 14px;text-align: ${textAlign};line-height: 1.4;">
|
|
963
|
-
<div>${localeService.t('Report approved by')}</div>
|
|
964
|
-
<div>${approvedBy}</div>
|
|
965
|
-
<img class="signature-image" style="height: 50px;width: auto;" src="${signature.signatureURL}">
|
|
966
|
-
</div>
|
|
967
|
-
</td>`;
|
|
968
|
-
});
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
if (data.labStamp && data.labType !== 18) {
|
|
972
|
-
content += `<td><img class="stamp-image a" style="padding: 0 25px;align-self: center;justify-self: center;webkit-align-items:center" src="${data.labStamp}" width="100"></td>`;
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
if (data.labType === 18) {
|
|
976
|
-
content += `<td><img class="stamp-image" style="float: right;padding: 0 25px;align-self: center;justify-self: center;webkit-align-items:center" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAADVCAYAAADtl80QAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAbXUAAHOgAAD83QAAg2QAAHDoAADsaAAAMD4AABCQ5OyZ6gAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAALNxJREFUeNrtXQeYVEW2np4ZZphhhiGIBAUZkkQJIohhwYyKWdeEiCKICUwYFhMgGFcFAwKKomDCgBl1FdEVFHFVQAQFBQWRIEpwhkndr477t+9u29NdVTfVvXP+7zvfvrfL3K7410l1KiODwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwdDD/wGlgtpU8FGP8wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNS0xMS0yMFQxMjo1MzoyOSswMTowMF975WEAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTUtMTEtMjBUMTI6NTM6MjkrMDE6MDAuJl3dAAAAAElFTkSuQmCC" width="100"></td>`;
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
return content;
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
function showDetailsView(data, isRtl) {
|
|
983
|
-
let biomarkerDetailsHtml = '';
|
|
984
|
-
let detailsSectionHTML = '';
|
|
985
|
-
let shouldShowSectionTitle = false;
|
|
986
|
-
|
|
987
|
-
data.panels.forEach((panel, counter) => {
|
|
988
|
-
/* Biomarker details template */
|
|
989
|
-
biomarkerDetailsHtml = renderBiomarkerDetails(panel, isRtl, counter);
|
|
990
|
-
|
|
991
|
-
/* Panel details template */
|
|
992
|
-
let checkShowInDetailsView = panel.biomarkers?.some(biomarker => biomarker.showInDetailsView);
|
|
993
|
-
|
|
994
|
-
if (panel.biomarkers && checkShowInDetailsView) {
|
|
995
|
-
shouldShowSectionTitle = true;
|
|
996
|
-
detailsSectionHTML += renderPanelDetails(panel, biomarkerDetailsHtml, counter, isRtl);
|
|
997
|
-
}
|
|
998
|
-
});
|
|
999
|
-
|
|
1000
|
-
return detailsSectionHTML;
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
function renderReportItems(items, isCompactView = false, isRtl = false, isRectified = false, isAllergyItem = false, allergyClasses = [], forPatient = false) {
|
|
1004
|
-
let content = '';
|
|
1005
|
-
let counter = 0;
|
|
1006
|
-
let itemCounter = 0;
|
|
1007
|
-
|
|
1008
|
-
items.forEach((dashboardItem, index) => {
|
|
1009
|
-
let nestingLevel = dashboardItem.nestingLevel;
|
|
1010
|
-
|
|
1011
|
-
if (isAllergyItem) {
|
|
1012
|
-
if (itemCounter === 0) {
|
|
1013
|
-
itemCounter++;
|
|
1014
|
-
return;
|
|
1015
|
-
}
|
|
1016
|
-
if (nestingLevel > 0) {
|
|
1017
|
-
nestingLevel -= 1;
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
let showInCompactView = dashboardItem.showInCompactView || false;
|
|
1022
|
-
let showInDetailsView = dashboardItem.showInDetailsView || false;
|
|
1023
|
-
|
|
1024
|
-
if (dashboardItem.biomarker || (dashboardItem.panel && dashboardItem.panel.panelBiomarker)) {
|
|
1025
|
-
let bio = dashboardItem.biomarker || dashboardItem.panel.panelBiomarker;
|
|
1026
|
-
counter++;
|
|
1027
|
-
let indentationStyle = nestingLevel > 0 ? `margin-left:${nestingLevel * INDENTATION.BIOMARKER_DETAILS}px` : '';
|
|
1028
|
-
|
|
1029
|
-
let biomarkerContent = isAllergyItem
|
|
1030
|
-
? renderAllergyBiomarker(bio, nestingLevel, dashboardItem.isChildBiomarker, isCompactView, false, isRtl, showInDetailsView, isRectified, allergyClasses, forPatient)
|
|
1031
|
-
: renderBiomarkerV3(bio, nestingLevel, dashboardItem.isChildBiomarker, isCompactView, false, isRtl, showInDetailsView, isRectified);
|
|
1032
|
-
|
|
1033
|
-
if (counter > 1 && !isCompactView && biomarkerContent) {
|
|
1034
|
-
content += '<hr class="biomarker-container-line b">';
|
|
1035
|
-
}
|
|
1036
|
-
content += biomarkerContent;
|
|
1037
|
-
} else if (dashboardItem.panel && !dashboardItem.panel.panelBiomarker && showInCompactView && isCompactView) {
|
|
1038
|
-
content += renderPanelV3(dashboardItem.panel, nestingLevel, isCompactView, itemCounter, isRectified, isAllergyItem);
|
|
1039
|
-
} else if (dashboardItem.panel && !dashboardItem.panel.panelBiomarker && showInDetailsView && !isCompactView) {
|
|
1040
|
-
counter = 0;
|
|
1041
|
-
content += renderPanelV3(dashboardItem.panel, nestingLevel, isCompactView, itemCounter, isRectified, isAllergyItem);
|
|
1042
|
-
} else if (dashboardItem.insight && dashboardItem.showInDetailsView && !isCompactView) {
|
|
1043
|
-
content += renderOneInsight(dashboardItem.insight, nestingLevel, isRtl);
|
|
1044
|
-
} else if (dashboardItem.biomarkerAttachment) {
|
|
1045
|
-
content += renderAttachmentsV3(dashboardItem.biomarkerAttachment, nestingLevel);
|
|
1046
|
-
} else if (dashboardItem.biomarkerDetailsList) {
|
|
1047
|
-
content += renderDetailsListV3(dashboardItem.biomarkerDetailsList, nestingLevel, isCompactView);
|
|
1048
|
-
} else if (dashboardItem.biomarkerNote) {
|
|
1049
|
-
content += renderNoteV3(dashboardItem.biomarkerNote, nestingLevel, isCompactView, showInCompactView, showInDetailsView);
|
|
1050
|
-
}
|
|
1051
|
-
itemCounter++;
|
|
1052
|
-
});
|
|
1053
|
-
|
|
1054
|
-
return content;
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
function renderBiomarkerV3(biomarker, nestingLevel, isChildBiomarker, isCompactView, isComponent = false, isRtl = false, showInDetailsView = true, isRectified = false) {
|
|
1058
|
-
let biomarkerCssId = `biomarker-${("db" + String(biomarker?.id ?? "")).toLowerCase()}${Math.floor(Math.random() * 3)}`;
|
|
1059
|
-
let newBiomarkerHtml = '';
|
|
1060
|
-
let biomarkerClass = '';
|
|
1061
|
-
let biomarkerParentValueStyle = '';
|
|
1062
|
-
let indentationStyle = '';
|
|
1063
|
-
|
|
1064
|
-
if (isCompactView && biomarker.showInCompactView) {
|
|
1065
|
-
let biomarkerName = biomarker.fullName || '';
|
|
1066
|
-
let biomarkerUnit = biomarker.unit;
|
|
1067
|
-
let biomarkerValue = biomarker.formattedValue || biomarker.lingualReading || '';
|
|
1068
|
-
let rangePlaceholder = '';
|
|
1069
|
-
let referenceRange = '';
|
|
1070
|
-
let biomarkerLast = '-';
|
|
1071
|
-
let biomarkerPast = '-';
|
|
1072
|
-
|
|
1073
|
-
if (shouldRenderReadingLevels(biomarker)) {
|
|
1074
|
-
rangePlaceholder = convertToMiniRangeLayout(biomarker.ranges, biomarker, isRtl);
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
if (biomarker.showScale) {
|
|
1078
|
-
let normalRangeObject = biomarker.ranges.find(range => range.isReference) || {};
|
|
1079
|
-
let formattedNormalRangeMin = normalRangeObject.formattedMinValue || null;
|
|
1080
|
-
let formattedNormalRangeMax = normalRangeObject.formattedMaxValue || null;
|
|
1081
|
-
referenceRange = biomarker.ranges.length > 1 ? getRange(biomarker) : '';
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
if (biomarker.color && !biomarker.isNormal) {
|
|
1085
|
-
biomarkerClass = 'risk';
|
|
1086
|
-
biomarkerParentValueStyle = `color:${biomarker.color};`;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
if (nestingLevel > 0) {
|
|
1090
|
-
let extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1091
|
-
let levelNesting = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS;
|
|
1092
|
-
indentationStyle = `padding-left: ${levelNesting}px`;
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
if (biomarker.history && biomarker.history.length > 1) {
|
|
1096
|
-
let lastBiomarkerIndex = biomarker.history.length - 2;
|
|
1097
|
-
biomarkerLast = biomarker.history[lastBiomarkerIndex]?.formattedValue || 0;
|
|
1098
|
-
biomarkerPast = biomarker.history[lastBiomarkerIndex]?.formattedDate || '-';
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
if (biomarkerValue.length > 35) {
|
|
1102
|
-
biomarkerParentValueStyle += "font-size:12px;line-height:1";
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
let firstTdWidth = '';
|
|
1106
|
-
let tdWidth = '';
|
|
1107
|
-
if (isCompactView) {
|
|
1108
|
-
let fullPanelWidth = INDENTATION.PAGE_WIDTH;
|
|
1109
|
-
let tdCount = 7;
|
|
1110
|
-
let RectifiedTd = isRectified ? 32 : 0;
|
|
1111
|
-
tdWidth = (fullPanelWidth - RectifiedTd) / tdCount;
|
|
1112
|
-
firstTdWidth = `${tdWidth * 2}px`;
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
let biomarkerNameAlign = isRtl ? 'text-align: right;' : '';
|
|
1116
|
-
const RTL_FLAG = '\u200E';
|
|
1117
|
-
|
|
1118
|
-
let isValueNumber = !isNaN(Number(biomarkerValue.replace(/\r\n/g, "<br/>")));
|
|
1119
|
-
let valueDataType = isValueNumber ? "number" : "string";
|
|
1120
|
-
let cleanBioMarkerUnit =
|
|
1121
|
-
biomarkerUnit
|
|
1122
|
-
.replace(/[\u200E\u200F\u202A-\u202E]/g, '')
|
|
1123
|
-
.replace(/\(/g, '(')
|
|
1124
|
-
.replace(/\)/g, ')');
|
|
1125
|
-
|
|
1126
|
-
newBiomarkerHtml += `<table id="${biomarkerCssId}" style="width:100%; margin: 0 auto;" class="biomarker-block biomarker-block-row ${biomarkerClass}">
|
|
1127
|
-
<tr>
|
|
1128
|
-
<td style="width:${firstTdWidth}">
|
|
1129
|
-
<div class="biom-title name" style="direction: ltr;${biomarkerNameAlign}${indentationStyle}">${biomarkerName}</div>
|
|
1130
|
-
<div class="biom-method method"></div>
|
|
1131
|
-
</td>
|
|
1132
|
-
<td class="biom-value value" style="width:max-content;">
|
|
1133
|
-
<span class="biom-parent-value value-text" data-type="${valueDataType}" style="${biomarkerParentValueStyle}">${biomarkerValue.replace(/\r\n/g, "<br/>")}</span>
|
|
1134
|
-
</td>
|
|
1135
|
-
${biomarkerUnit ?
|
|
1136
|
-
`<td class="biom-unit unit">
|
|
1137
|
-
<div class="biom-parent-unit unit-text" style="padding: 0 6px; font-family: 'Open Sans', sans-serif !important; direction: ltr !important; unicode-bidi: isolate !important;" dir="ltr">
|
|
1138
|
-
${cleanBioMarkerUnit}
|
|
1139
|
-
</div>
|
|
1140
|
-
</td>` : ''}
|
|
1141
|
-
${rangePlaceholder ? `<td class="biom-bar listing" style="width:${tdWidth}px; margin: 0;"><div class="range-placeholder b">${rangePlaceholder}</div></td>` : ''}
|
|
1142
|
-
<td class="biom-range biom-range-data" style="width:${tdWidth}px; margin: 0;"><div class="parent-reference-range range">${referenceRange}</div></td>
|
|
1143
|
-
</tr>
|
|
1144
|
-
</table>`;
|
|
1145
|
-
}
|
|
1146
|
-
// ${isRtl ?RTL_FLAG+cleanBioMarkerUnit:cleanBioMarkerUnit}
|
|
1147
|
-
if (!isCompactView && showInDetailsView) {
|
|
1148
|
-
newBiomarkerHtml += renderOneBiomarker(biomarker, isRtl, nestingLevel, isChildBiomarker, isComponent);
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
if (biomarker.components && biomarker.components.length > 0) {
|
|
1152
|
-
biomarker.components.forEach(comp => {
|
|
1153
|
-
comp.showInDetailsView = biomarker.showInDetailsView;
|
|
1154
|
-
comp.showInCompactView = biomarker.showInCompactView;
|
|
1155
|
-
comp.formattedNormalRangeMin = comp.min;
|
|
1156
|
-
comp.formattedNormalRangeMax = comp.max;
|
|
1157
|
-
newBiomarkerHtml += renderBiomarkerV3(comp, nestingLevel, isChildBiomarker, isCompactView, true, isRtl, showInDetailsView, isRectified);
|
|
1158
|
-
});
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
if ((isCompactView && biomarker.showInCompactView) || (!isCompactView && biomarker.showInDetailsView)) {
|
|
1162
|
-
if (biomarker.notes && biomarker.notes.length > 0) {
|
|
1163
|
-
let BioNoteStyle = '';
|
|
1164
|
-
if (nestingLevel > 0) {
|
|
1165
|
-
let extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1166
|
-
let paddingLeft = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS + 8;
|
|
1167
|
-
BioNoteStyle = isRtl ? `padding-right:${paddingLeft}px` : `padding-left:${paddingLeft}px`;
|
|
1168
|
-
}
|
|
1169
|
-
let notesPadding = isRtl ? 'padding: 0px 16px 10px 0px;' : 'padding: 0px 0px 10px 16px;';
|
|
1170
|
-
let classNote = !isCompactView ? 'note-margin-bottom' : '';
|
|
1171
|
-
if (useMonospace) {
|
|
1172
|
-
const monoStyle = `font-style: normal; font-size: 13px; color: #333; font-family: 'Roboto Mono', monospace; white-space: pre-wrap; overflow-x: auto;`;
|
|
1173
|
-
newBiomarkerHtml += `<div class="biomarker-notes 2 ${classNote}" style="${notesPadding} ${BioNoteStyle}"><span style="${monoStyle}">${biomarker.notes.join('<br/>')}</span></div>`;
|
|
1174
|
-
} else {
|
|
1175
|
-
newBiomarkerHtml += `<div class="biomarker-notes 2 ${classNote}" style="color: #8F8F92; ${notesPadding} ${BioNoteStyle}">${biomarker.notes.join('<br/>')}</div>`;
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
return newBiomarkerHtml;
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
function renderPanelV3(panel, nestingLevel, isCompactView, counter = null, isRectified = false, isAllergyItem = false) {
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
const panelCssId = `panel-${panel.panelId}db${Math.floor(Math.random() * 3)}`;
|
|
1187
|
-
const notes = panel.notes ? panel.notes.join('') : '';
|
|
1188
|
-
let classPanel = '';
|
|
1189
|
-
if (panel.doctorNotes && isCompactView) {
|
|
1190
|
-
classPanel = 'panel-with-notes';
|
|
1191
|
-
}
|
|
1192
|
-
let panelWidth = isCompactView ? 'width:687px' : '';
|
|
1193
|
-
const colspan = isCompactView ? '1' : '4';
|
|
1194
|
-
const doctorNotesCompactView = panel.doctorNotes && isCompactView
|
|
1195
|
-
? `<div class="section-content">${renderDoctorNotesCompactView(panel.doctorNotes, nestingLevel)}</div>`
|
|
1196
|
-
: '';
|
|
1197
|
-
const doctorNotesDetailsView = panel.doctorNotes && !isCompactView
|
|
1198
|
-
? `<div class="section-content-details-view">${renderDoctorNotes(panel.doctorNotes, nestingLevel)}</div>`
|
|
1199
|
-
: '';
|
|
1200
|
-
let newBiomarkerHtml = '';
|
|
1201
|
-
let panelClass = '';
|
|
1202
|
-
if (counter === 0 && !isCompactView) {
|
|
1203
|
-
panelClass = "first-panel";
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
newBiomarkerHtml += `<!--panel-->
|
|
1207
|
-
<div id="${panelCssId}" class="section panel dontend ${panelClass}">`;
|
|
1208
|
-
|
|
1209
|
-
let panelNesting = "margin-left: auto;";
|
|
1210
|
-
let panelTitleFontSize = '';
|
|
1211
|
-
if (nestingLevel > 0) {
|
|
1212
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1213
|
-
const levelNesting = extraPadding + nestingLevel * INDENTATION.PANEL_TITLE;
|
|
1214
|
-
panelWidth = INDENTATION.PAGE_WIDTH - levelNesting;
|
|
1215
|
-
panelNesting = `margin-left: ${levelNesting}px;width: ${panelWidth}px;`;
|
|
1216
|
-
panelTitleFontSize = 'font-size:18px';
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
let firstTdWidth = '';
|
|
1220
|
-
const RectifiedTd = isRectified ? 32 : 0;
|
|
1221
|
-
let tdWidth = 0; // Declare tdWidth here to make it accessible outside the if block
|
|
1222
|
-
if (isCompactView) {
|
|
1223
|
-
const fullPanelWidth = INDENTATION.PAGE_WIDTH;
|
|
1224
|
-
const tdCount = 7;
|
|
1225
|
-
|
|
1226
|
-
tdWidth = (fullPanelWidth - RectifiedTd) / tdCount;
|
|
1227
|
-
firstTdWidth = `${tdWidth * 2}px`;
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
newBiomarkerHtml += `<div class="section-content-header ${classPanel}">
|
|
1231
|
-
<div class="panel-title" style="box-sizing: border-box; ${panelNesting}">
|
|
1232
|
-
<table style="width:100%; margin: 0 auto;" class="biomarker-block panel-section-header-new">
|
|
1233
|
-
<tr>`;
|
|
1234
|
-
|
|
1235
|
-
let allergyItemPanelClass = '';
|
|
1236
|
-
if (isAllergyItem && isAllergyItem) {
|
|
1237
|
-
allergyItemPanelClass = 'allergy-panel';
|
|
1238
|
-
if (panel.icon) {
|
|
1239
|
-
newBiomarkerHtml += `<td class="panel-icon-container">
|
|
1240
|
-
<img src="${panel.icon}"/>
|
|
1241
|
-
</td>`;
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
newBiomarkerHtml += `<td colspan="${colspan}" style="width:${firstTdWidth}">
|
|
1246
|
-
<div class="panel-title-text ${allergyItemPanelClass}" style="${panelTitleFontSize}">${panel.name}</div>
|
|
1247
|
-
${doctorNotesCompactView}`;
|
|
1248
|
-
|
|
1249
|
-
if (notes) {
|
|
1250
|
-
newBiomarkerHtml += `<div class="panel-notes">${notes}</div>`;
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
newBiomarkerHtml += `</td>`;
|
|
1254
|
-
|
|
1255
|
-
if (isCompactView) {
|
|
1256
|
-
newBiomarkerHtml += `<td class="biom-range" style="width:${tdWidth}px; margin: 0;">
|
|
1257
|
-
${localeService.t('Reference range')}
|
|
1258
|
-
</td>
|
|
1259
|
-
|
|
1260
|
-
`;
|
|
1261
|
-
if (isRectified) {
|
|
1262
|
-
newBiomarkerHtml += `<td class="biom-past" style="width:${RectifiedTd}px"></td>`;
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
newBiomarkerHtml += `</tr></table>
|
|
1267
|
-
</div>
|
|
1268
|
-
</div>
|
|
1269
|
-
${doctorNotesDetailsView}
|
|
1270
|
-
<!--panel END-->`;
|
|
1271
|
-
|
|
1272
|
-
return newBiomarkerHtml;
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
function renderAttachmentsV3(attachment, nestingLevel) {
|
|
1276
|
-
if (!attachment) return '';
|
|
1277
|
-
|
|
1278
|
-
let blockStyle = '';
|
|
1279
|
-
if (nestingLevel > 0) {
|
|
1280
|
-
let extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1281
|
-
let levelNesting = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS;
|
|
1282
|
-
blockStyle = `padding-left: ${levelNesting}px`;
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
let ext = attachment.split(';');
|
|
1286
|
-
if (ext[0].toLowerCase() === "data:application/pdf") {
|
|
1287
|
-
return '';
|
|
1288
|
-
} else {
|
|
1289
|
-
let pos = attachment.indexOf(';');
|
|
1290
|
-
let type = attachment.substring(0, pos).split(';');
|
|
1291
|
-
if (type[0].includes('svg')) {
|
|
1292
|
-
return `<div style="${blockStyle}" class="biomarker-attachment-item">${attachment}</div>`;
|
|
1293
|
-
} else {
|
|
1294
|
-
return `<img ${nestingLevel} style="${blockStyle};max-width:320px" class="biomarker-attachment-item" src="${attachment}" />`;
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
function renderDetailsListV3(detailsList, nestingLevel, isCompactView) {
|
|
1300
|
-
let maxRowLength = -1;
|
|
1301
|
-
let content = '';
|
|
1302
|
-
let itemsCount = detailsList.map(item => item.length);
|
|
1303
|
-
let colspanColumn = Math.max(...itemsCount);
|
|
1304
|
-
|
|
1305
|
-
detailsList.forEach(row => {
|
|
1306
|
-
content += "<tr>";
|
|
1307
|
-
row.forEach(item => {
|
|
1308
|
-
let colspan = row.length === 1 ? colspanColumn : 1;
|
|
1309
|
-
content += `<td colspan="${colspan}">${item}</td>`;
|
|
1310
|
-
});
|
|
1311
|
-
|
|
1312
|
-
if (row.length > maxRowLength) {
|
|
1313
|
-
maxRowLength = row.length;
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
if (row.length < maxRowLength) {
|
|
1317
|
-
content += (row.length < colspanColumn && row.length !== 1) ? fillEmptyCellsWith(maxRowLength - row.length) : '';
|
|
1318
|
-
}
|
|
1319
|
-
content += "</tr>";
|
|
1320
|
-
});
|
|
1321
|
-
|
|
1322
|
-
let blockStyle = '';
|
|
1323
|
-
let plusPadding = isCompactView ? 8 : 18;
|
|
1324
|
-
if (nestingLevel > 0) {
|
|
1325
|
-
let extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1326
|
-
let levelNesting = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS + plusPadding;
|
|
1327
|
-
blockStyle = `padding-left: ${levelNesting}px`;
|
|
1328
|
-
}
|
|
1329
|
-
|
|
1330
|
-
return `<div style="${blockStyle}" class="biomarker-details-table" style="padding:0 ${plusPadding}px"><table>${content}</table></div>`;
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
function renderNoteV3(note, nestingLevel, isCompactView, showInCompactView, showInDetailsView) {
|
|
1334
|
-
// Standalone biomarkerNote items duplicate the note already rendered inside
|
|
1335
|
-
// renderBiomarkerV3 (biomarker.notes), so they are intentionally suppressed
|
|
1336
|
-
// here to avoid every note appearing twice. Monospace styling for PHA is
|
|
1337
|
-
// handled where biomarker.notes is rendered.
|
|
1338
|
-
return '';
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
function renderAllergyClasses(allergyClasses, isRtl = false) {
|
|
1342
|
-
let count = allergyClasses.length;
|
|
1343
|
-
let tableFloat = isRtl ? 'float: left;' : 'float: right;';
|
|
1344
|
-
let unitAlign = isRtl ? 'text-align: left;right: 0;' : 'text-align: right;left: 0;';
|
|
1345
|
-
let content = `<div class="allergy-classes-container">
|
|
1346
|
-
<span class="allergy-classes-unit" style="${unitAlign}">kU/L</span>
|
|
1347
|
-
<table class="allergy-classes-table colored" width="100%" cellspacing="0" cellpadding="0" style="${tableFloat}">
|
|
1348
|
-
<tr><td colspan="${count}" class="allergy-classes-table-title">${localeService.t('Allergy Reaction Strength')}</td></tr>`;
|
|
1349
|
-
|
|
1350
|
-
let tr1 = '<tr>';
|
|
1351
|
-
let tr2 = '<tr>';
|
|
1352
|
-
|
|
1353
|
-
allergyClasses.forEach(classItem => {
|
|
1354
|
-
let formattedMinValue = classItem.formattedMinValue;
|
|
1355
|
-
let formattedMaxValue = classItem.formattedMaxValue;
|
|
1356
|
-
let range = '';
|
|
1357
|
-
|
|
1358
|
-
if (!formattedMinValue && formattedMaxValue) {
|
|
1359
|
-
range = `< ${formattedMaxValue}`;
|
|
1360
|
-
}
|
|
1361
|
-
if (formattedMinValue && formattedMaxValue) {
|
|
1362
|
-
range = `${formattedMinValue} - ${formattedMaxValue}`;
|
|
1363
|
-
}
|
|
1364
|
-
if (formattedMinValue && !formattedMaxValue) {
|
|
1365
|
-
range = `> ${formattedMinValue}`;
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
tr1 += `<td style="color:${classItem.color}">${classItem.className}</td>`;
|
|
1369
|
-
tr2 += `<td style="color:${classItem.color}">${classItem.lingualReading}<br/>${range}</td>`;
|
|
1370
|
-
});
|
|
1371
|
-
|
|
1372
|
-
tr1 += '</tr>';
|
|
1373
|
-
tr2 += '</tr>';
|
|
1374
|
-
|
|
1375
|
-
content += tr1 + tr2 + '</table></div>';
|
|
1376
|
-
return content;
|
|
1377
|
-
}
|
|
1378
|
-
|
|
1379
|
-
function renderAllergyBiomarker(biomarker, nestingLevel, isChildBiomarker, isCompactView, isComponent = false, isRtl = false, showInDetailsView = true, isRectified = false, allergyClasses = [], forPatient = true) {
|
|
1380
|
-
let newBiomarkerHtml = '';
|
|
1381
|
-
|
|
1382
|
-
if (!isCompactView && showInDetailsView) {
|
|
1383
|
-
newBiomarkerHtml += renderOneAllergyBiomarker(biomarker, isRtl, nestingLevel, isChildBiomarker, isComponent, allergyClasses, forPatient);
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
// Render its values inside components element
|
|
1387
|
-
if (biomarker.components && biomarker.components.length > 0) {
|
|
1388
|
-
biomarker.components.forEach(comp => {
|
|
1389
|
-
comp.showInDetailsView = biomarker.showInDetailsView;
|
|
1390
|
-
comp.showInCompactView = biomarker.showInCompactView;
|
|
1391
|
-
comp.formattedNormalRangeMin = comp.min;
|
|
1392
|
-
comp.formattedNormalRangeMax = comp.max;
|
|
1393
|
-
newBiomarkerHtml += renderAllergyBiomarker(comp, nestingLevel, isChildBiomarker, isCompactView, true, isRtl, showInDetailsView, isRectified, allergyClasses, forPatient);
|
|
1394
|
-
});
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
return newBiomarkerHtml;
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
function renderOneAllergyBiomarker(biomarker, isRtl, nestingLevel, isChildBiomarker, isComponent, allergyClasses, forPatient) {
|
|
1401
|
-
const INDENTATION = {
|
|
1402
|
-
BIOMARKER_DETAILS: 20, // Example value, replace with actual value
|
|
1403
|
-
PANEL_TITLE: 10 // Example value, replace with actual value
|
|
1404
|
-
};
|
|
1405
|
-
|
|
1406
|
-
let biomarkerDetailsHtml = '';
|
|
1407
|
-
if (biomarker.showInDetailsView === true) {
|
|
1408
|
-
const biomarkerCssId = "dtl-bio-db" + String(biomarker?.id ?? "").toLowerCase();
|
|
1409
|
-
let customBiomarkerValueFontSize = '';
|
|
1410
|
-
const formattedValue = biomarker.formattedValue.replace(/,/g, "");
|
|
1411
|
-
if (formattedValue.length > 35) {
|
|
1412
|
-
customBiomarkerValueFontSize = 'font-size:12px;';
|
|
1413
|
-
}
|
|
1414
|
-
const biomarkerName = biomarker.name || '';
|
|
1415
|
-
const biomarkerStatus = biomarker.status || '';
|
|
1416
|
-
const insightsCount = biomarker.insightsCount || '';
|
|
1417
|
-
let CircleStyles = '';
|
|
1418
|
-
if (!isComponent) {
|
|
1419
|
-
CircleStyles = GetBiomarkerCircleStyle(biomarker.color, biomarkerName, biomarkerStatus, insightsCount, '', false);
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
// indent biomarker details based on panel level
|
|
1423
|
-
let firstGridColClass = 'size5';
|
|
1424
|
-
let bioIndentStyle = '';
|
|
1425
|
-
let bioIndentNoteStyle = '';
|
|
1426
|
-
if (nestingLevel > 0) {
|
|
1427
|
-
// replace classes
|
|
1428
|
-
// increase biomarker part
|
|
1429
|
-
firstGridColClass = 'size5';
|
|
1430
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1431
|
-
const levelNesting = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS;
|
|
1432
|
-
const levelNestingNote = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS + 16;
|
|
1433
|
-
bioIndentStyle = 'padding-left: ' + levelNesting + 'px;';
|
|
1434
|
-
bioIndentNoteStyle = 'padding-left: ' + levelNestingNote + 'px';
|
|
1435
|
-
}
|
|
1436
|
-
|
|
1437
|
-
// @note: IMC special case (large biomarker value)
|
|
1438
|
-
let biomarkerClass = '';
|
|
1439
|
-
if (biomarker.formattedValue.length >= 125) {
|
|
1440
|
-
biomarkerClass = 'large-value-class';
|
|
1441
|
-
firstGridColClass = '';
|
|
1442
|
-
//$firstGridColstyle = 'width:100%';
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
const biomarkerValue = biomarker.formattedValue.replace(/\r\n/g, "<br/>");
|
|
1446
|
-
|
|
1447
|
-
if (!biomarker.showScale) {
|
|
1448
|
-
biomarkerClass += ' hide-scale ';
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
const biomarkerColor = biomarker.color && !biomarker.isNormal ? "color:" + biomarker.color + ";" : "";
|
|
1452
|
-
let rangesPlaceholder = "";
|
|
1453
|
-
let currentRange = "";
|
|
1454
|
-
let currentPercent = 25;
|
|
1455
|
-
let biomarkerTitleClass = '';
|
|
1456
|
-
if (biomarker.ranges.length > 1) {
|
|
1457
|
-
biomarkerTitleClass = 'has-ranges';
|
|
1458
|
-
} else {
|
|
1459
|
-
biomarkerTitleClass = 'has-no-ranges';
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
let childRangesPlaceholder = "";
|
|
1463
|
-
let childCurrentRange = "";
|
|
1464
|
-
let heightCount = 1;
|
|
1465
|
-
let bioValue = "";
|
|
1466
|
-
let bioUnit = "";
|
|
1467
|
-
let afterBioInfoValue = '';
|
|
1468
|
-
let History = '';
|
|
1469
|
-
if (biomarker.childrenBiomarkers && biomarker.childrenBiomarkers.length > 0) {
|
|
1470
|
-
biomarker.childrenBiomarkers.forEach(bio => {
|
|
1471
|
-
if (bio.ranges.length > 1) {
|
|
1472
|
-
heightCount++;
|
|
1473
|
-
/* viewing the biomarker and unit of children after the parent ones */
|
|
1474
|
-
bioValue = bio.formattedValue.replace(/\n/g, "<br />");
|
|
1475
|
-
let bioValue_style = "";
|
|
1476
|
-
if (bioValue.length > 33) {
|
|
1477
|
-
bioValue_style = "font-size:12px;";
|
|
1478
|
-
}
|
|
1479
|
-
bioUnit = bio.unit;
|
|
1480
|
-
childCurrentRange = '';
|
|
1481
|
-
/* generating the children ranges and display them under the parent ones */
|
|
1482
|
-
childRangesPlaceholder += '<div class="extra-range-placeholder">'
|
|
1483
|
-
+ convertToRangeLayout(bio.ranges, bio, isRtl)
|
|
1484
|
-
+ '</div>';
|
|
1485
|
-
biomarkerTitleClass = 'has-ranges';
|
|
1486
|
-
afterBioInfoValue += '<div class="colorable pair">'
|
|
1487
|
-
+ '<span class="biomarker-extra-value" style="' + bioValue_style + '">' + bioValue + '</span>'
|
|
1488
|
-
+ '<span class="biomarker-extra-unit">' + bioUnit + '</span>'
|
|
1489
|
-
+ '</div>';
|
|
1490
|
-
} else {
|
|
1491
|
-
biomarkerTitleClass = 'has-no-ranges';
|
|
1492
|
-
}
|
|
1493
|
-
/*
|
|
1494
|
-
$History = renderBiomarkerHistoryChart($bio);
|
|
1495
|
-
*/
|
|
1496
|
-
});
|
|
1497
|
-
} else {
|
|
1498
|
-
/*
|
|
1499
|
-
$History = renderBiomarkerHistoryChart($biomarker);
|
|
1500
|
-
*/
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
if (heightCount > 1) {
|
|
1504
|
-
biomarkerClass += 'hide-flag';
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
/* set biomarker history chart */
|
|
1508
|
-
|
|
1509
|
-
const biomarkerFullName = biomarker.fullName || '';
|
|
1510
|
-
let bioName = biomarkerFullName.replace(/\r\n/g, '');
|
|
1511
|
-
bioName = bioName.replace(/\n/g, '');
|
|
1512
|
-
const rangePlaceHolder = convertToRangeLayout(biomarker.ranges, biomarker, isRtl);
|
|
1513
|
-
let biomarkerSampleHTML = '';
|
|
1514
|
-
let biomInfoStyle = '';
|
|
1515
|
-
let biomValueAlignStyle = '';
|
|
1516
|
-
if (biomarker.sample) {
|
|
1517
|
-
biomarkerSampleHTML += '<div class="biom-sample">'
|
|
1518
|
-
+ '<span class="biom-sample-value">'
|
|
1519
|
-
+ biomarker.sample
|
|
1520
|
-
+ '</span>'
|
|
1521
|
-
+ '</div>';
|
|
1522
|
-
// $biomValueAlignStyle = "vertical-align: bottom;";
|
|
1523
|
-
}
|
|
1524
|
-
if (!biomarker.sample && (rangePlaceHolder || childRangesPlaceholder || History)) {
|
|
1525
|
-
biomInfoStyle = "margin-top:15px;";
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
// Configurations
|
|
1529
|
-
let biomarkerScale = '';
|
|
1530
|
-
if (isChildBiomarker) {
|
|
1531
|
-
// $biomarkerScale = 'transform:scale(.9);';
|
|
1532
|
-
}
|
|
1533
|
-
let biomCircleCss = '';
|
|
1534
|
-
if (isComponent) {
|
|
1535
|
-
biomCircleCss = 'opacity: 0;';
|
|
1536
|
-
biomarkerSampleHTML = '';
|
|
1537
|
-
bioName = '';
|
|
1538
|
-
}
|
|
1539
|
-
let panelNesting = '';
|
|
1540
|
-
let biomarkerTitleWidth = 'width:260px';
|
|
1541
|
-
if (nestingLevel > 0) {
|
|
1542
|
-
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1543
|
-
const levelNesting = extraPadding + nestingLevel * INDENTATION.PANEL_TITLE;
|
|
1544
|
-
panelNesting = isRtl ? 'padding-right: ' + levelNesting + 'px;box-sizing:border-box;' : 'padding-left: ' + levelNesting + 'px;box-sizing:border-box;';
|
|
1545
|
-
const width = 260 - levelNesting;
|
|
1546
|
-
biomarkerTitleWidth = 'width:' + width + 'px';
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1549
|
-
if (!rangePlaceHolder && !childRangesPlaceholder && !History) {
|
|
1550
|
-
biomarkerScale += 'width:100%;';
|
|
1551
|
-
}
|
|
1552
|
-
const doctorNotesArr = biomarker.doctorNotes || [];
|
|
1553
|
-
const doctorNotes = renderDoctorNotes(doctorNotesArr, bioIndentNoteStyle);
|
|
1554
|
-
|
|
1555
|
-
biomarkerDetailsHtml += '<div data-id="' + biomarkerCssId + '" class="allergy-biomarker-container biomarker-container grid-col ' + biomarkerClass + '">'
|
|
1556
|
-
+ '<!--panel title was her in the first biomarker -->'
|
|
1557
|
-
+ '<div class="grid-col ' + firstGridColClass + ' ' + biomarkerClass + '" style="' + biomarkerScale + panelNesting + '">'
|
|
1558
|
-
+ '<div class="biomarker">'
|
|
1559
|
-
+ '<div class="biom-circle" style="' + removeWhiteSpace(CircleStyles) + ';' + biomCircleCss + '">' + biomarkerName + '</div>'
|
|
1560
|
-
+ '<div class="biom-info ' + biomarkerTitleClass + '" style="' + biomInfoStyle + '">'
|
|
1561
|
-
+ '<div class="title ' + biomarkerTitleClass + '" style="' + biomarkerTitleWidth + '">' + biomarkerSampleHTML + '<span class="bio-name-info a" style="color: #555558;">' + bioName + '</span></div>'
|
|
1562
|
-
+ '<div class="value colorable" style="' + biomValueAlignStyle + '">'
|
|
1563
|
-
+ biomarkerSampleHTML
|
|
1564
|
-
+ '<div class="pair parent-pair">'
|
|
1565
|
-
+ '<span class="value-text">'
|
|
1566
|
-
+ '<span style="' + customBiomarkerValueFontSize + biomarkerColor + '">' + biomarkerValue + '</span>'
|
|
1567
|
-
+ '</span>'
|
|
1568
|
-
+ '<span class="unit colorable">' + biomarker.unit + '</span>'
|
|
1569
|
-
+ '</div>'
|
|
1570
|
-
+ '</div>'
|
|
1571
|
-
+ afterBioInfoValue
|
|
1572
|
-
+ '</div>'
|
|
1573
|
-
+ '</div>';
|
|
1574
|
-
|
|
1575
|
-
if (doctorNotes) {
|
|
1576
|
-
biomarkerDetailsHtml += '<div class="grid-row biomarker-insights a">'
|
|
1577
|
-
+ doctorNotes
|
|
1578
|
-
+ '</div>';
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
if (biomarker.notes && biomarker.notes.length > 0) {
|
|
1582
|
-
if (nestingLevel > 0) {
|
|
1583
|
-
// $extraPadding = (($nestingLevel + 10 % 10) + 1);
|
|
1584
|
-
// $levelNesting = $extraPadding + $nestingLevel * $INDENTATION['BIOMARKER_DETAILS'] + 5;
|
|
1585
|
-
// $bioIndentStyle = 'padding-left: ' . $levelNesting . 'px;';
|
|
1586
|
-
}
|
|
1587
|
-
bioIndentStyle = isRtl ? 'padding-right: 16px;' : 'padding-left: 16px;';
|
|
1588
|
-
|
|
1589
|
-
if (useMonospace) {
|
|
1590
|
-
const monoStyle = `font-style: normal; font-size: 13px; color: #333; font-family: 'Roboto Mono', monospace; white-space: pre-wrap; overflow-x: auto;`;
|
|
1591
|
-
biomarkerDetailsHtml += '<div class="biomarker-notes 1" style="padding-top: 10px;' + bioIndentStyle + '">';
|
|
1592
|
-
biomarkerDetailsHtml += `<span style="${monoStyle}">` + biomarker.notes.join('<br/>') + '</span>';
|
|
1593
|
-
biomarkerDetailsHtml += '</div>';
|
|
1594
|
-
} else {
|
|
1595
|
-
biomarkerDetailsHtml += '<div class="biomarker-notes 1" style="color: #8F8F92;padding-top: 10px;' + bioIndentStyle + '">';
|
|
1596
|
-
biomarkerDetailsHtml += biomarker.notes.join('<br/>');
|
|
1597
|
-
biomarkerDetailsHtml += '</div>';
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
biomarkerDetailsHtml += '</div> <!-- end first col -->';
|
|
1601
|
-
|
|
1602
|
-
if (allergyClasses) {
|
|
1603
|
-
const rangeIndex = biomarker.rangeIndex;
|
|
1604
|
-
biomarkerDetailsHtml += '<table class="allergy-classes-table" width="100%" cellspacing="0" cellpadding="0" range="' + rangeIndex + '">';
|
|
1605
|
-
|
|
1606
|
-
let tr1 = '<tr>';
|
|
1607
|
-
|
|
1608
|
-
allergyClasses.forEach((cls, index) => { // Renamed 'class' to 'cls' to avoid conflict
|
|
1609
|
-
const formattedMinValue = cls.formattedMinValue;
|
|
1610
|
-
const formattedMaxValue = cls.formattedMaxValue;
|
|
1611
|
-
let range = '';
|
|
1612
|
-
|
|
1613
|
-
if (!formattedMinValue && formattedMaxValue) {
|
|
1614
|
-
range = `< ${formattedMaxValue}`;
|
|
1615
|
-
} else if (formattedMinValue && formattedMaxValue) {
|
|
1616
|
-
range = `${formattedMinValue} - ${formattedMaxValue}`;
|
|
1617
|
-
} else if (formattedMinValue && !formattedMaxValue) {
|
|
1618
|
-
range = `> ${formattedMinValue}`;
|
|
1619
|
-
}
|
|
1620
|
-
|
|
1621
|
-
let value = '';
|
|
1622
|
-
|
|
1623
|
-
if (index === rangeIndex) {
|
|
1624
|
-
let currentRange = biomarker.ranges[rangeIndex];
|
|
1625
|
-
let currentPercent = 0;
|
|
1626
|
-
|
|
1627
|
-
if (currentRange.minValue !== undefined && currentRange.maxValue !== undefined) {
|
|
1628
|
-
currentPercent = ((parseFloat(biomarker.value) - currentRange.minValue) / (currentRange.maxValue - currentRange.minValue)) * 100;
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
currentPercent = Math.max(8, Math.min(77, currentPercent)); // Ensures percent is between 8 and 77
|
|
1632
|
-
const imagePlace = isRtl ? `right: ${currentPercent}%` : `left: ${currentPercent}%`;
|
|
1633
|
-
|
|
1634
|
-
value = `<span index="${rangeIndex}" class="colored-value" patient="${forPatient}" style="background:${cls.color}">`;
|
|
1635
|
-
|
|
1636
|
-
if (!forPatient) {
|
|
1637
|
-
value += biomarker.formattedValue;
|
|
1638
|
-
} else {
|
|
1639
|
-
value += `<span style="${imagePlace}" class="white-circle"></span>`;
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
value += `</span>`;
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
tr1 += `<td>${value}</td>`;
|
|
1646
|
-
});
|
|
1647
|
-
allergyClasses.forEach((cls, index) => { // Renamed 'class' to 'cls' to avoid conflict
|
|
1648
|
-
const formattedMinValue = cls.formattedMinValue;
|
|
1649
|
-
const formattedMaxValue = cls.formattedMaxValue;
|
|
1650
|
-
let range = '';
|
|
1651
|
-
|
|
1652
|
-
if (!formattedMinValue && formattedMaxValue) {
|
|
1653
|
-
range = `< ${formattedMaxValue}`;
|
|
1654
|
-
} else if (formattedMinValue && formattedMaxValue) {
|
|
1655
|
-
range = `${formattedMinValue} - ${formattedMaxValue}`;
|
|
1656
|
-
} else if (formattedMinValue && !formattedMaxValue) {
|
|
1657
|
-
range = `> ${formattedMinValue}`;
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1660
|
-
let value = '';
|
|
1661
|
-
|
|
1662
|
-
if (index === rangeIndex) {
|
|
1663
|
-
let currentRange = biomarker.ranges[rangeIndex];
|
|
1664
|
-
let currentPercent = 0;
|
|
1665
|
-
|
|
1666
|
-
if (currentRange.minValue !== undefined && currentRange.maxValue !== undefined) {
|
|
1667
|
-
currentPercent = ((parseFloat(biomarker.value) - currentRange.minValue) / (currentRange.maxValue - currentRange.minValue)) * 100;
|
|
1668
|
-
}
|
|
1669
|
-
|
|
1670
|
-
currentPercent = Math.max(8, Math.min(77, currentPercent)); // Ensures percent is between 8 and 77
|
|
1671
|
-
const imagePlace = isRtl ? `right: ${currentPercent}%` : `left: ${currentPercent}%`;
|
|
1672
|
-
|
|
1673
|
-
value = `<span index="${rangeIndex}" class="colored-value" patient="${forPatient}" style="background:${cls.color}">`;
|
|
1674
|
-
|
|
1675
|
-
if (!forPatient) {
|
|
1676
|
-
value += biomarker.formattedValue;
|
|
1677
|
-
} else {
|
|
1678
|
-
value += `<span style="${imagePlace}" class="white-circle"></span>`;
|
|
1679
|
-
}
|
|
1680
|
-
|
|
1681
|
-
value += `</span>`;
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
|
-
tr1 += `<td>${value}</td>`;
|
|
1685
|
-
});
|
|
1686
|
-
|
|
1687
|
-
tr1 += '</tr>';
|
|
1688
|
-
biomarkerDetailsHtml += tr1 + '</table>';
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
|
-
biomarkerDetailsHtml += '</div> <!-- end first close biomarker-container-->';
|
|
1692
|
-
}
|
|
1693
|
-
return biomarkerDetailsHtml;
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1696
|
-
// Helper functions (assuming they exist in your code)
|
|
1697
|
-
function GetBiomarkerCircleStyle(BiomarkerColor, BiomarkerName, BiomarkerStatus, BiomarkerInsightsCount, PanelName, isSummary, item = []) {
|
|
1698
|
-
let CircleStyles = '';
|
|
1699
|
-
let fontSize = BiomarkerName && BiomarkerName.length > 6 ? '12px' : '14px';
|
|
1700
|
-
let color = BiomarkerColor || "#555555";
|
|
1701
|
-
let BioColor = BiomarkerColor || "#E05A5A";
|
|
1702
|
-
let backgroundColor = BioColor ? 'transparent' : "#E05A5A30";
|
|
1703
|
-
|
|
1704
|
-
if (isSummary) {
|
|
1705
|
-
CircleStyles = `background-color: ${backgroundColor}; border: 2px solid ${BioColor}; color: ${color}; font-size: ${fontSize};`;
|
|
1706
|
-
} else {
|
|
1707
|
-
BioColor = BiomarkerColor || "#555555";
|
|
1708
|
-
CircleStyles = `background-color: transparent; border: 2px solid ${BioColor}; color: ${color}; font-size: ${fontSize};`;
|
|
1709
|
-
}
|
|
1710
|
-
|
|
1711
|
-
if ((BiomarkerInsightsCount !== undefined && BiomarkerStatus !== undefined) || BiomarkerInsightsCount === null || BiomarkerStatus === null) {
|
|
1712
|
-
backgroundColor = (BiomarkerInsightsCount || PanelName.toLowerCase() === 'health risk calculators') ? BiomarkerColor : "transparent";
|
|
1713
|
-
let BiomarkerBorder = (BiomarkerInsightsCount || PanelName.toLowerCase() === 'health risk calculators') ? `2px solid ${BiomarkerColor}` : `2px solid ${BiomarkerColor}`;
|
|
1714
|
-
color = BiomarkerInsightsCount ? "#ffffff" : BiomarkerColor;
|
|
1715
|
-
fontSize = BiomarkerName && PanelName.toLowerCase().length > 6 ? "12px" : "14px";
|
|
1716
|
-
|
|
1717
|
-
CircleStyles = `background-color: ${backgroundColor}; border: ${BiomarkerBorder}; color: ${color}; font-size: ${fontSize};`;
|
|
1718
|
-
|
|
1719
|
-
if (BiomarkerStatus !== 1 && BiomarkerStatus !== "1") {
|
|
1720
|
-
fontSize = BiomarkerName && BiomarkerName.length > 7 ? "12px" : "14px";
|
|
1721
|
-
CircleStyles = `background-color: transparent; border: 2px solid rgba(0,0,0,.4); color: rgba(0,0,0,.4); font-size: ${fontSize};`;
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
return CircleStyles;
|
|
1725
|
-
}
|
|
1726
|
-
|
|
1727
|
-
function convertToRangeLayout(ranges, biomarker, isRtl) {
|
|
1728
|
-
|
|
1729
|
-
let barHTML = '';
|
|
1730
|
-
if (ranges.length > 1) {
|
|
1731
|
-
barHTML += '<table>';
|
|
1732
|
-
let tr1 = '<tr class="ranges">';
|
|
1733
|
-
let tr2 = '<tr class="labels">';
|
|
1734
|
-
let tr3 = '<tr class="values">';
|
|
1735
|
-
let currentPercent = 50;
|
|
1736
|
-
let currentRange = "";
|
|
1737
|
-
|
|
1738
|
-
ranges.forEach(range => {
|
|
1739
|
-
let isCurrentClass = range.isCurrent ? "current" : "";
|
|
1740
|
-
let labelClass = range.isCurrent ? 'colorable' : "";
|
|
1741
|
-
let rangeTitle = '';
|
|
1742
|
-
let rangeArrow = '';
|
|
1743
|
-
|
|
1744
|
-
if (range.isCurrent) {
|
|
1745
|
-
currentRange = `${range.minValue} - ${range.maxValue}`;
|
|
1746
|
-
if (range.minValue && range.maxValue) {
|
|
1747
|
-
currentPercent = (((parseFloat(biomarker.value) - range.minValue) / (range.maxValue - range.minValue)) * 100);
|
|
1748
|
-
}
|
|
1749
|
-
currentPercent = Math.min(90, currentPercent);
|
|
1750
|
-
let imagePlace = isRtl ? `padding-right:${currentPercent}%` : `padding-left:${currentPercent}%`;
|
|
1751
|
-
rangeArrow = `<img class="range-arrow-layout" style="${imagePlace}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAYAAADFw8lbAAAAAXNSR0IArs4c6QAAATBJREFUWAnNjgmOAjEQA/M0P90/23UhsdICw1w5uqSgIem2q7XWnPNT/ODYlFNdFMcHzm9VWdz+UL6qiuL2D+dfNVmc3lBuqoni9BHntoosLpsoL1VEcfmK87paFoddlInVojgcwplaJUv3YZTJVaJ0n8KZni1L52mUjdmidF7C2ZolS9dllM1ZonTdwtkeLUvHbZSE0aJ0dMFJGSVLdjeUpFGiZHfFSestS2Z3lMTeomQOwUntJUvWMJTkXqJkDcVJvytLxnCUhruiZEzBabkqy+40lKarouxOxWk7K8vOdJTGs6LsLMFpPSrL7DKU5qOizC7Fad+TZWY5isGeKDMlcCy2ZHkrg2KyJcpbKRybV1nuyqEYvYpyVxLH6inLd1kUs6co36Vx7DjlUQw5XfkFNeBu5tFKZ1EAAAAASUVORK5CYII="/>`;
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
rangeTitle = getRangeBar(biomarker, range, biomarker.normalRangeType);
|
|
1755
|
-
let colorClass = color(range.color);
|
|
1756
|
-
tr1 += `<td style="background-position-x:${currentPercent}%;" class="${colorClass} ${isCurrentClass}">${rangeArrow}<div class="range colorablebg" style="background:${colorClass}"></div></td>`;
|
|
1757
|
-
tr2 += `<td class="${isCurrentClass} ${colorClass}"><span class="${labelClass}">${range.name}</span></td>`;
|
|
1758
|
-
tr3 += `<td>${rangeTitle}</td>`;
|
|
1759
|
-
});
|
|
1760
|
-
|
|
1761
|
-
barHTML += tr1 + '</tr>' + tr3 + '</tr>' + tr2 + '</tr>';
|
|
1762
|
-
barHTML += '</table>';
|
|
1763
|
-
}
|
|
1764
|
-
return barHTML;
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
function removeWhiteSpace(html) {
|
|
1769
|
-
html = html.replace(/\r\n/g, "");
|
|
1770
|
-
return html.replace(/>\s+</g, "><");
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
|
-
function fetchFileContents(filePath) {
|
|
1774
|
-
try {
|
|
1775
|
-
return fs.readFileSync(filePath, 'utf8');
|
|
1776
|
-
} catch (error) {
|
|
1777
|
-
console.error('Error reading file:', error);
|
|
1778
|
-
return null;
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
function parseTable(string) {
|
|
1783
|
-
let levels = string.split("\n");
|
|
1784
|
-
let list = levels.map(level => {
|
|
1785
|
-
return {
|
|
1786
|
-
id: random(2, 6),
|
|
1787
|
-
content: level,
|
|
1788
|
-
sepCount: separtorsNumbers(level)
|
|
1789
|
-
};
|
|
1790
|
-
});
|
|
1791
|
-
|
|
1792
|
-
let parent = list[0].sepCount;
|
|
1793
|
-
|
|
1794
|
-
for (let i = 0; i < list.length; i++) {
|
|
1795
|
-
if (i === 0) {
|
|
1796
|
-
list[i].parent_id = "0";
|
|
1797
|
-
continue;
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
if (parent === list[i].sepCount) {
|
|
1801
|
-
list[i].parent_id = "0";
|
|
1802
|
-
continue;
|
|
1803
|
-
}
|
|
1804
|
-
|
|
1805
|
-
if (list[i - 1]) {
|
|
1806
|
-
if (list[i].sepCount > list[i - 1].sepCount) {
|
|
1807
|
-
list[i].parent_id = list[i - 1].id;
|
|
1808
|
-
} else if (list[i].sepCount === list[i - 1].sepCount) {
|
|
1809
|
-
list[i].parent_id = list[i - 1].parent_id;
|
|
1810
|
-
} else {
|
|
1811
|
-
list[i].parent_id = findParentId(i - 1, list[i].sepCount, list);
|
|
1812
|
-
}
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
|
|
1816
|
-
return list_to_tree(list, "0");
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
function renderDetails(list, isRtl) {
|
|
1820
|
-
if (list.length === 1 && !list[0].children) {
|
|
1821
|
-
return `<li class="1">${list[0].content.substring(list[0].sepCount)}</li>`;
|
|
1822
|
-
}
|
|
1823
|
-
|
|
1824
|
-
let columns = [];
|
|
1825
|
-
let isParent = false;
|
|
1826
|
-
|
|
1827
|
-
list.forEach(child => {
|
|
1828
|
-
if (child.parent_id === "0") isParent = true;
|
|
1829
|
-
let div = '';
|
|
1830
|
-
|
|
1831
|
-
if (!child.children) {
|
|
1832
|
-
let childContent = child.content.substring(child.sepCount);
|
|
1833
|
-
childContent = childContent.replace('(', '(').replace(')', ')');
|
|
1834
|
-
|
|
1835
|
-
if (isRtl) {
|
|
1836
|
-
// Optional RTL handling here
|
|
1837
|
-
}
|
|
1838
|
-
|
|
1839
|
-
div = `<li class="2">${childContent}</li>`;
|
|
1840
|
-
} else {
|
|
1841
|
-
div = `<li class="arrow-icon">${child.content.substring(child.sepCount)}</li>
|
|
1842
|
-
<ul>${renderDetails(child.children, isRtl)}</ul>`;
|
|
1843
|
-
}
|
|
1844
|
-
|
|
1845
|
-
if (div) columns.push(div);
|
|
1846
|
-
});
|
|
1847
|
-
|
|
1848
|
-
return columns.length > 0 ? columns.join('') : null;
|
|
1849
|
-
}
|
|
1850
|
-
|
|
1851
|
-
function GetRelatedBiomarker(biomarkerstyle, name, fullname) {
|
|
1852
|
-
let fontSize = '';
|
|
1853
|
-
if (name && fullname) {
|
|
1854
|
-
if (name.length >= 7) {
|
|
1855
|
-
fontSize = 'small-fontSize-circle';
|
|
1856
|
-
}
|
|
1857
|
-
return `<div class="related">
|
|
1858
|
-
<div class="bicon ${fontSize}" style="${biomarkerstyle}">
|
|
1859
|
-
<span class="bicon-inner">${name}</span>
|
|
1860
|
-
</div>
|
|
1861
|
-
</div>`;
|
|
1862
|
-
}
|
|
1863
|
-
return null;
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
|
-
function color(hex) {
|
|
1867
|
-
switch (hex) {
|
|
1868
|
-
case "#E05A5A":
|
|
1869
|
-
return "red";
|
|
1870
|
-
case "#EE734E":
|
|
1871
|
-
return "orange";
|
|
1872
|
-
case "#41B9D6":
|
|
1873
|
-
return "blue";
|
|
1874
|
-
case "#F7AA2E":
|
|
1875
|
-
return "yellow";
|
|
1876
|
-
case "#BC2828":
|
|
1877
|
-
return "dark-red";
|
|
1878
|
-
case "#02D9D1":
|
|
1879
|
-
case "#05B9AF":
|
|
1880
|
-
return "green";
|
|
1881
|
-
case "#0F0F0F":
|
|
1882
|
-
return "black";
|
|
1883
|
-
case "#87B7CE":
|
|
1884
|
-
return "lightblue";
|
|
1885
|
-
case "#FB7377":
|
|
1886
|
-
return "light-red";
|
|
1887
|
-
default:
|
|
1888
|
-
return hex;
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
|
|
1892
|
-
function getRangeBar(item, level, normalRangeType = '') {
|
|
1893
|
-
|
|
1894
|
-
let range = '';
|
|
1895
|
-
let min = level.formattedMinValue;
|
|
1896
|
-
let max = level.formattedMaxValue;
|
|
1897
|
-
|
|
1898
|
-
if (item.ranges && item.ranges.length > 0) {
|
|
1899
|
-
let customBioWithTwoRangesAndNormalExist = false;
|
|
1900
|
-
if (item.isCustom && item.ranges.length === 2) {
|
|
1901
|
-
let normalRange = item.ranges.find(range => range.isReference);
|
|
1902
|
-
if (normalRange) customBioWithTwoRangesAndNormalExist = true;
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
|
-
let rangeIndex = item.ranges.findIndex(range => range.isReference);
|
|
1906
|
-
|
|
1907
|
-
let readingLevels = item.ranges;
|
|
1908
|
-
let prevItem = rangeIndex - 1;
|
|
1909
|
-
|
|
1910
|
-
if (max !== null || min !== null) {
|
|
1911
|
-
|
|
1912
|
-
if (level.isReference === true) {
|
|
1913
|
-
switch (normalRangeType) {
|
|
1914
|
-
case 0 | "0":
|
|
1915
|
-
range = min !== null && max !== null ? `${min} - ${max}` : min === null ? `<= ${max}` : `>= ${min}`;
|
|
1916
|
-
|
|
1917
|
-
if (prevItem >= 0 && readingLevels[prevItem]?.formattedMaxValue === min) {
|
|
1918
|
-
range = `> ${min}`;
|
|
1919
|
-
}
|
|
1920
|
-
break;
|
|
1921
|
-
case 1 | "1":
|
|
1922
|
-
range = `< ${max}`;
|
|
1923
|
-
break;
|
|
1924
|
-
case 2 | "2":
|
|
1925
|
-
range = `<= ${max}`;
|
|
1926
|
-
break;
|
|
1927
|
-
case 3 | "3":
|
|
1928
|
-
range = `> ${min}`;
|
|
1929
|
-
break;
|
|
1930
|
-
case 4 | "4":
|
|
1931
|
-
range = `>= ${min}`;
|
|
1932
|
-
break;
|
|
1933
|
-
}
|
|
1934
|
-
} else {
|
|
1935
|
-
range = min !== null && max !== null ? `${min} - ${max}` : min === null ? `< ${max}` : `> ${min}`;
|
|
1936
|
-
if (prevItem >= 0 && readingLevels[prevItem]?.formattedMaxValue === min) {
|
|
1937
|
-
range = `>= ${min}`;
|
|
1938
|
-
if (prevItem >= 0 && readingLevels[prevItem]?.formattedMaxValue === min) {
|
|
1939
|
-
range = `> ${min}`;
|
|
1940
|
-
}
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
|
-
if (customBioWithTwoRangesAndNormalExist) {
|
|
1944
|
-
switch (normalRangeType) {
|
|
1945
|
-
case "0":
|
|
1946
|
-
range = min !== null && max !== null ? `${min} - ${max}` : min === null ? `< ${max}` : `> ${min}`;
|
|
1947
|
-
break;
|
|
1948
|
-
case "1":
|
|
1949
|
-
range = min !== null ? `>= ${min}` : range;
|
|
1950
|
-
break;
|
|
1951
|
-
case "2":
|
|
1952
|
-
range = min !== null ? `> ${min}` : range;
|
|
1953
|
-
break;
|
|
1954
|
-
case "3":
|
|
1955
|
-
range = max !== null ? `<= ${max}` : range;
|
|
1956
|
-
break;
|
|
1957
|
-
case "4":
|
|
1958
|
-
range = max !== null ? `< ${max}` : range;
|
|
1959
|
-
break;
|
|
1960
|
-
}
|
|
1961
|
-
}
|
|
1962
|
-
}
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
return range;
|
|
1966
|
-
}
|
|
1967
|
-
|
|
1968
|
-
function separtorsNumbers(string) {
|
|
1969
|
-
let last = string.lastIndexOf('#');
|
|
1970
|
-
let first = string.indexOf('#');
|
|
1971
|
-
|
|
1972
|
-
if (first !== -1 && first !== 0) {
|
|
1973
|
-
return 0;
|
|
1974
|
-
}
|
|
1975
|
-
|
|
1976
|
-
let subString = string.substring(first, last + 1);
|
|
1977
|
-
let mySplits = subString.split('');
|
|
1978
|
-
let isLevel = mySplits.every(char => char === "#");
|
|
1979
|
-
|
|
1980
|
-
return isLevel ? mySplits.length : separtorsNumbers(string.substring(first, last));
|
|
1981
|
-
}
|
|
1982
|
-
|
|
1983
|
-
function shouldRenderReadingLevels(biomarker, isComponentItem = false) {
|
|
1984
|
-
return biomarker && biomarker.ranges.length > 1 && (biomarker.showScale || isComponentItem);
|
|
1985
|
-
}
|
|
1986
|
-
|
|
1987
|
-
function convertToMiniRangeLayout(ranges, biomarker, isRtl) {
|
|
1988
|
-
let barHTML = '';
|
|
1989
|
-
|
|
1990
|
-
if (ranges.length > 0) {
|
|
1991
|
-
barHTML += '<div class="bar">';
|
|
1992
|
-
ranges.forEach(range => {
|
|
1993
|
-
let colorClass = color(range.color);
|
|
1994
|
-
let label = range.name;
|
|
1995
|
-
let isCurrentClass = range.isCurrent ? "current" : "";
|
|
1996
|
-
let rangeTitle = `${range.minValue} - ${range.maxValue}`;
|
|
1997
|
-
let imgCurrent = '';
|
|
1998
|
-
|
|
1999
|
-
if (range.isCurrent) {
|
|
2000
|
-
let currentRange = `${range.minValue} - ${range.maxValue}`;
|
|
2001
|
-
let currentPercent = null;
|
|
2002
|
-
if (range.minValue && range.maxValue) {
|
|
2003
|
-
currentPercent = (((parseFloat(biomarker.value) - range.minValue) / (range.maxValue - range.minValue)) * 100);
|
|
2004
|
-
}
|
|
2005
|
-
currentPercent = currentPercent / 2;
|
|
2006
|
-
let imagePlace = currentPercent ? `left: ${currentPercent}%` : '';
|
|
2007
|
-
if (isRtl) {
|
|
2008
|
-
imagePlace = currentPercent ? `right: ${currentPercent}%` : '';
|
|
2009
|
-
}
|
|
2010
|
-
imgCurrent = `<img style="${imagePlace}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhBAMAAAClyt9cAAAAHlBMVEUAAAD///////////////////////////////////8kfJuVAAAACXRSTlMA8ObIrYNJLyOprz29AAAAaUlEQVQoz2OgPyg1mmRagCzQMhMIpjQgBNgkZ4KAGEIkcyYEJMAEOCShIhIwEZaZUDAFJlI5EwZg1kXCRQKgIpZwEQOoiCZcRAEqMhMOJmCqwTQH0y5M92C4GdNfmH7HCB/MMMQMZ7oDAAe/ZbNL9bq2AAAAAElFTkSuQmCC" />`;
|
|
2011
|
-
}
|
|
2012
|
-
barHTML += `<div class="segment ${colorClass} ${isCurrentClass}" style="background:${colorClass}">${imgCurrent}</div>`;
|
|
2013
|
-
});
|
|
2014
|
-
barHTML += '</div>';
|
|
2015
|
-
}
|
|
2016
|
-
return barHTML;
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
function getRange(item, normalRangeKey = "isReference") {
|
|
2020
|
-
let range = '';
|
|
2021
|
-
if (item.ranges && item.ranges.length > 0) {
|
|
2022
|
-
let itemValues = item.ranges.find(range => range[normalRangeKey] === true);
|
|
2023
|
-
let rangeIndex = item.ranges.findIndex(range => range[normalRangeKey] === true);
|
|
2024
|
-
let readingLevels = item.ranges;
|
|
2025
|
-
|
|
2026
|
-
let max = itemValues?.formattedMaxValue ?? null;
|
|
2027
|
-
let min = itemValues?.formattedMinValue ?? null;
|
|
2028
|
-
let normalRangeType = item.normalRangeType;
|
|
2029
|
-
let prevItem = rangeIndex - 1;
|
|
2030
|
-
|
|
2031
|
-
if (max !== null || min !== null) {
|
|
2032
|
-
if (max !== null && min !== null) {
|
|
2033
|
-
range = `${min} - ${max}`;
|
|
2034
|
-
} else if (max !== null) {
|
|
2035
|
-
range = `< ${max}`;
|
|
2036
|
-
} else if (min !== null) {
|
|
2037
|
-
range = `> ${min}`;
|
|
2038
|
-
}
|
|
2039
|
-
|
|
2040
|
-
switch (String(normalRangeType)) {
|
|
2041
|
-
case "0":
|
|
2042
|
-
if (max !== null && min !== null) {
|
|
2043
|
-
range = `${min} - ${max}`;
|
|
2044
|
-
} else if (max !== null) {
|
|
2045
|
-
range = `<= ${max}`;
|
|
2046
|
-
} else if (min !== null) {
|
|
2047
|
-
range = `>= ${min}`;
|
|
2048
|
-
}
|
|
2049
|
-
break;
|
|
2050
|
-
case "1":
|
|
2051
|
-
if (max !== null) range = `< ${max}`;
|
|
2052
|
-
break;
|
|
2053
|
-
case "2":
|
|
2054
|
-
if (max !== null) range = `<= ${max}`;
|
|
2055
|
-
break;
|
|
2056
|
-
case "3":
|
|
2057
|
-
if (min !== null) range = `> ${min}`;
|
|
2058
|
-
break;
|
|
2059
|
-
case "4":
|
|
2060
|
-
if (min !== null) range = `>= ${min}`;
|
|
2061
|
-
break;
|
|
2062
|
-
}
|
|
2063
|
-
}
|
|
2064
|
-
}
|
|
2065
|
-
return range;
|
|
2066
|
-
}
|
|
2067
|
-
|
|
2068
|
-
function find(array, key, value) {
|
|
2069
|
-
for (let single of array) {
|
|
2070
|
-
if (single[key] === value) {
|
|
2071
|
-
return single;
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
return null;
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
function renderBiomarkerHistoryChart(biomarker) {
|
|
2078
|
-
let content = '';
|
|
2079
|
-
const history = biomarker.history && biomarker.history.length > 0 ? biomarker.history : [];
|
|
2080
|
-
|
|
2081
|
-
// Custom biomarker shouldn't have a chart
|
|
2082
|
-
if (history.length > 1) {
|
|
2083
|
-
const biomarkerCssChartId = "chart-bio-db" +
|
|
2084
|
-
Math.random().toString(36).substring(2, 8) +
|
|
2085
|
-
String(biomarker?.id ?? "").toLowerCase();
|
|
2086
|
-
content += `<canvas id="${biomarkerCssChartId}" width="100%" height="30" class="chart-canvas"></canvas>`;
|
|
2087
|
-
const dataset = [];
|
|
2088
|
-
const dataColor = [];
|
|
2089
|
-
const dataColorLabels = [];
|
|
2090
|
-
const dataLabel = [];
|
|
2091
|
-
const unit = [];
|
|
2092
|
-
const dataFormattedValues = [];
|
|
2093
|
-
|
|
2094
|
-
history.forEach((item, index) => {
|
|
2095
|
-
dataset[index] = parseInt(biomarker.type) ? parseFloat(item.value) : item.rangeIndex;
|
|
2096
|
-
dataFormattedValues[index] = item.formattedValue;
|
|
2097
|
-
dataColor[index] = item.color;
|
|
2098
|
-
dataColorLabels[index] = item.color === "#E05A5A" ? item.color : "rgba(51,51,51, 0.8)";
|
|
2099
|
-
dataLabel[index] = item.formattedDate;
|
|
2100
|
-
unit[index] = item.unit;
|
|
2101
|
-
});
|
|
2102
|
-
|
|
2103
|
-
const maxOfChart = Math.max(...dataset) + 0.5;
|
|
2104
|
-
const differenceRange = Math.max(...dataset) - Math.min(...dataset);
|
|
2105
|
-
let stepSizeNumber = 0.5;
|
|
2106
|
-
if (differenceRange > 100) {
|
|
2107
|
-
stepSizeNumber = 0;
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
|
-
content += `
|
|
2111
|
-
<script>
|
|
2112
|
-
$(document).ready(function() {
|
|
2113
|
-
function showChart() {
|
|
2114
|
-
const ctx = document.getElementById("${biomarkerCssChartId}").getContext("2d");
|
|
2115
|
-
new Chart(ctx, {
|
|
2116
|
-
type: "line",
|
|
2117
|
-
data: {
|
|
2118
|
-
labels: ${JSON.stringify(dataLabel)},
|
|
2119
|
-
datasets: [{
|
|
2120
|
-
data: ${JSON.stringify(dataset)},
|
|
2121
|
-
dataFormattedValues: ${JSON.stringify(dataFormattedValues)},
|
|
2122
|
-
pointBorderColor: "transparent",
|
|
2123
|
-
pointRadius: 6,
|
|
2124
|
-
pointBorderWidth: 2,
|
|
2125
|
-
lineTension: 0,
|
|
2126
|
-
fill: false,
|
|
2127
|
-
pointBackgroundColor: ${JSON.stringify(dataColor)},
|
|
2128
|
-
fill: false
|
|
2129
|
-
}]
|
|
2130
|
-
},
|
|
2131
|
-
options: {
|
|
2132
|
-
layout: {
|
|
2133
|
-
padding: {
|
|
2134
|
-
top: 30,
|
|
2135
|
-
bottom: 30,
|
|
2136
|
-
left: 50,
|
|
2137
|
-
right: 40
|
|
2138
|
-
}
|
|
2139
|
-
},
|
|
2140
|
-
legend: {
|
|
2141
|
-
display: false,
|
|
2142
|
-
fontColor: "black"
|
|
2143
|
-
},
|
|
2144
|
-
tooltips: { enabled: false },
|
|
2145
|
-
plugins: {
|
|
2146
|
-
datalabels: {
|
|
2147
|
-
display: "block",
|
|
2148
|
-
color: ${JSON.stringify(dataColorLabels)},
|
|
2149
|
-
align: "top",
|
|
2150
|
-
anchor: "end",
|
|
2151
|
-
clamp: true,
|
|
2152
|
-
clip: false,
|
|
2153
|
-
font: {
|
|
2154
|
-
lineHeight: 1.2,
|
|
2155
|
-
size: 12,
|
|
2156
|
-
style: "normal"
|
|
2157
|
-
},
|
|
2158
|
-
formatter: function(value, context) {
|
|
2159
|
-
return " " + context.dataset.dataFormattedValues[context.dataIndex];
|
|
2160
|
-
}
|
|
2161
|
-
}
|
|
2162
|
-
},
|
|
2163
|
-
document: true,
|
|
2164
|
-
window: true,
|
|
2165
|
-
hover: false,
|
|
2166
|
-
beginAtZero: false,
|
|
2167
|
-
responsive: true,
|
|
2168
|
-
maintainAspectRatio: true,
|
|
2169
|
-
scales: {
|
|
2170
|
-
yAxes: [{
|
|
2171
|
-
ticks: {
|
|
2172
|
-
suggestedMax: ${maxOfChart},
|
|
2173
|
-
suggestedMin: 0,
|
|
2174
|
-
stepSize: ${stepSizeNumber}
|
|
2175
|
-
},
|
|
2176
|
-
display: false
|
|
2177
|
-
}],
|
|
2178
|
-
xAxes: [{
|
|
2179
|
-
gridLines: {
|
|
2180
|
-
display: false
|
|
2181
|
-
}
|
|
2182
|
-
}]
|
|
2183
|
-
},
|
|
2184
|
-
animation: {
|
|
2185
|
-
onComplete: function() {
|
|
2186
|
-
window.JSREPORT_READY_TO_START = true;
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
});
|
|
2191
|
-
}
|
|
2192
|
-
setTimeout(showChart, 200);
|
|
2193
|
-
});
|
|
2194
|
-
</script>
|
|
2195
|
-
`;
|
|
2196
|
-
}
|
|
2197
|
-
|
|
2198
|
-
return content;
|
|
2199
|
-
}
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
module.exports = {
|
|
2203
|
-
renderReportItems,
|
|
2204
|
-
find,
|
|
2205
|
-
renderSummary,
|
|
2206
|
-
renderReportSummary,
|
|
2207
|
-
renderHTMLTemplate,
|
|
2208
|
-
renderAllergyClasses,
|
|
2209
|
-
setUseMonospace,
|
|
2210
|
-
}
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
1
|
+
const LocaleService = require('../app/services/localeService.js');
|
|
2
|
+
const i18n = require('../app/i18n_wellbeing.config.js');
|
|
3
|
+
fetchFileContents
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
let useMonospace = false;
|
|
8
|
+
function setUseMonospace(val) { useMonospace = val; }
|
|
9
|
+
const INDENTATION = {
|
|
10
|
+
PANEL_TITLE: 12,
|
|
11
|
+
BIOMARKER_DETAILS: 12,
|
|
12
|
+
INSIGHT: 12,
|
|
13
|
+
PAGE_WIDTH: 794
|
|
14
|
+
};
|
|
15
|
+
var localeService = new LocaleService(i18n);
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
function renderHTMLTemplate(html, isRtl, data, isIMCLab, lang = 'en') {
|
|
19
|
+
let dir = isRtl ? 'rtl' : 'ltr';
|
|
20
|
+
let language = isRtl ? 'ar' : 'en';
|
|
21
|
+
let IMCclass = isIMCLab ? 'imc-lab' : '';
|
|
22
|
+
let styles = fetchFileContents(path.resolve(__dirname, '../assets/medicus_pdf/styles.css'));
|
|
23
|
+
if (isRtl) {
|
|
24
|
+
styles += fetchFileContents(path.resolve(__dirname, '../assets/medicus_pdf/arabic.css'));
|
|
25
|
+
}
|
|
26
|
+
let bodyClass = "";
|
|
27
|
+
if (!data['approvalDate']) {
|
|
28
|
+
bodyClass = "draft-bg";
|
|
29
|
+
if (lang !== 'en' && ['ar', 'de', 'fr', 'nl-NL', 'pt', 'pt_BR', 'ar-SA'].includes(lang)) {
|
|
30
|
+
|
|
31
|
+
bodyClass = "draft-bg-" + lang;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (data['labType'] === 18) {
|
|
35
|
+
bodyClass += ' smart-donor';
|
|
36
|
+
}
|
|
37
|
+
const fs = require('fs');
|
|
38
|
+
let content = `
|
|
39
|
+
<div>
|
|
40
|
+
<div id="page_template" class="all-pages ${IMCclass}">
|
|
41
|
+
|
|
42
|
+
${html}
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
return content;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function returnIntroTemplate(data, isIMCLab) {
|
|
51
|
+
let profileItemHTML = '';
|
|
52
|
+
let classProfileItemContainer = "size4";
|
|
53
|
+
let widthProfileItemContainer = '';
|
|
54
|
+
let introWidth = '';
|
|
55
|
+
if (isIMCLab || (!process.env.SHOW_QR_BOX || process.env.SHOW_QR_BOX === "false")) {
|
|
56
|
+
classProfileItemContainer = '';
|
|
57
|
+
widthProfileItemContainer = 'width:100%';
|
|
58
|
+
introWidth = 'width:100%';
|
|
59
|
+
|
|
60
|
+
let length = 100 / 3;
|
|
61
|
+
let items = data['profileItems'];
|
|
62
|
+
if (data['reportProperties'] && isIMCLab) {
|
|
63
|
+
for (const [key, value] of Object.entries(data['reportProperties'])) {
|
|
64
|
+
items.push({title: key, value: value});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for (const item of items) {
|
|
69
|
+
profileItemHTML += `<div style='width: ${length}%; padding: 10px 0' class='grid-col size2'>
|
|
70
|
+
<div class='info-label'>${item.title}</div>
|
|
71
|
+
<div class='info-value'>${item.value}</div>
|
|
72
|
+
</div>`;
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
let index = 0;
|
|
76
|
+
while (index < data['profileItems'].length - 1) {
|
|
77
|
+
let newDivId = 'sub' + index;
|
|
78
|
+
profileItemHTML += `<div id="${newDivId}" class='grid-row'>`;
|
|
79
|
+
|
|
80
|
+
for (let j = 0; j < 2; j++) {
|
|
81
|
+
let valueId = newDivId + '-' + j;
|
|
82
|
+
let profileItemValue = data['profileItems'][index]['value'];
|
|
83
|
+
let classAttr = /[A-Za-z]/.test(profileItemValue) && /[0-9]/.test(profileItemValue) ? "ltr_dir" : "";
|
|
84
|
+
|
|
85
|
+
profileItemHTML += `<div id='${valueId}' class='grid-col size2'>
|
|
86
|
+
<div class='info-label'>${data['profileItems'][index]['title']}</div>
|
|
87
|
+
<div class='info-value ${classAttr}'>${profileItemValue}</div>
|
|
88
|
+
</div>`;
|
|
89
|
+
index++;
|
|
90
|
+
}
|
|
91
|
+
profileItemHTML += `</div>`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (data['profileItems'].length % 2 !== 0) {
|
|
95
|
+
let newDivId = 'sub' + index;
|
|
96
|
+
let valueId = newDivId + '-0';
|
|
97
|
+
let profileItemValue = data['profileItems'][index]['value'];
|
|
98
|
+
let classAttr = /[A-Za-z]/.test(profileItemValue) && /[0-9]/.test(profileItemValue) ? "ltr_dir" : "";
|
|
99
|
+
|
|
100
|
+
profileItemHTML += `<div id="${newDivId}" class='grid-row'>
|
|
101
|
+
<div id='${valueId}' class='grid-col size2'>
|
|
102
|
+
<div class='info-label'>${data['profileItems'][index]['title']}</div>
|
|
103
|
+
<div class='info-value ${classAttr}'>${profileItemValue}</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let moreLink = localeService.t('Access your detailed report online') + " ";
|
|
110
|
+
moreLink = moreLink.replace("{link}", `<strong><a href='${data['moreLink']}' target='_blank'>${data['moreLink']}</a></strong>`);
|
|
111
|
+
|
|
112
|
+
if (data['patientPin'] && data['showPIN'] && data['qrCode']) {
|
|
113
|
+
moreLink += localeService.t("Scan this report’s QR code or enter this PIN code:") + "";
|
|
114
|
+
} else if (data['patientPin'] && data['showPIN']) {
|
|
115
|
+
moreLink += localeService.t("Enter this PIN code:") + "";
|
|
116
|
+
} else if (data['qrCode']) {
|
|
117
|
+
moreLink += localeService.t("Scan this report’s QR code:") + "";
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
let content = '';
|
|
121
|
+
let pin = data['patientPin'] || '';
|
|
122
|
+
let qrImage = data['qrCode'] || '';
|
|
123
|
+
let displayPin = pin ? 'inline-block' : 'none';
|
|
124
|
+
let displayQR = qrImage ? 'inline-block' : 'none';
|
|
125
|
+
let reportTitle = data['labType'] === 18 ? 'Smart Report' : localeService.t('Smart Report');
|
|
126
|
+
|
|
127
|
+
content += `<div class="intro" style="${introWidth}">
|
|
128
|
+
<div class="grid-row">
|
|
129
|
+
<div class="profile-items-container grid-col ${classProfileItemContainer}" style="${widthProfileItemContainer}">
|
|
130
|
+
<div id="report-title-header-ltr" class="report-title">
|
|
131
|
+
<div class="heading">${reportTitle}</div>
|
|
132
|
+
</div>
|
|
133
|
+
<div id="patient-container">${profileItemHTML}</div>
|
|
134
|
+
</div>`;
|
|
135
|
+
|
|
136
|
+
if (!isIMCLab && (process.env.SHOW_QR_BOX === "true" || process.env.SHOW_QR_BOX === true) && data['labType'] !== 18) {
|
|
137
|
+
content += `<div class="plus-info-container grid-col size4">
|
|
138
|
+
<div class="plus-info">
|
|
139
|
+
<div class="grid-row">
|
|
140
|
+
<div class="grid-col size3">
|
|
141
|
+
<div id="more-link" class="description">${moreLink}
|
|
142
|
+
<span id="pin" class="pin" style="display:${displayPin}">${pin}</span>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
<div class="grid-col size1 qr-container">
|
|
146
|
+
<div id="qrcode" class="pin-qr" style="display:${displayQR}"><img src="${qrImage}"></div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
content += '</div></div>';
|
|
154
|
+
|
|
155
|
+
return content;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
function renderDoctorNotes(doctorNotes, bioIndentStyle = '') {
|
|
160
|
+
let doctorNotesHTML = '';
|
|
161
|
+
if (doctorNotes && doctorNotes.length > 0) {
|
|
162
|
+
doctorNotes.forEach(note => {
|
|
163
|
+
let noteId = 'doctor-note-' + Math.random().toString(36).substr(2, 9);
|
|
164
|
+
doctorNotesHTML += `<div class="card-wrapper card-wrapper-note" style="${bioIndentStyle}">
|
|
165
|
+
<div id="${noteId}" class="card">
|
|
166
|
+
<div class="icon">
|
|
167
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
|
168
|
+
<g fill="none" fill-rule="evenodd">
|
|
169
|
+
<rect width="32" height="32" fill="" rx="16"/>
|
|
170
|
+
<g fill="#295C42" fill-rule="nonzero">
|
|
171
|
+
<path d="M20.613 23.8a.31.31 0 0 0 .217-.088l1.845-1.8a.296.296 0 0 0 .09-.212v-12c0-.166-.137-.3-.307-.3h-1.845a.304.304 0 0 0-.308.3c0 .166.138.3.308.3h1.537v11.576l-1.755 1.712a.295.295 0 0 0 0 .424.31.31 0 0 0 .218.088z"/>
|
|
172
|
+
<path d="M11.387 10c.17 0 .308-.134.308-.3 0-.166-.138-.3-.308-.3H9.542a.304.304 0 0 0-.307.3v12.9c0 .662.552 1.2 1.23 1.2h8.918c.17 0 .307-.134.307-.3v-1.8c0-.136.137-.3.308-.3h1.23c.17 0 .307-.134.307-.3 0-.166-.137-.3-.307-.3h-1.23c-.492 0-.923.42-.923.9v1.5h-8.61a.608.608 0 0 1-.615-.6V10h1.537zM16 8.2c-.34 0-.615.27-.615.6 0 .33.276.6.615.6.34 0 .615-.27.615-.6 0-.33-.276-.6-.615-.6z"/>
|
|
173
|
+
<path d="M22.458 8.2h-1.845a.304.304 0 0 0-.308.3c0 .166.138.3.308.3h1.845c.448 0 .922.463.922.9v13.8c0 .437-.474.9-.922.9H9.542c-.448 0-.922-.463-.922-.9V9.7c0-.437.474-.9.922-.9h1.845c.17 0 .308-.134.308-.3 0-.166-.138-.3-.308-.3H9.542c-.79 0-1.537.729-1.537 1.5v13.8c0 .771.747 1.5 1.537 1.5h12.916c.79 0 1.537-.729 1.537-1.5V9.7c0-.771-.747-1.5-1.537-1.5z"/>
|
|
174
|
+
</g>
|
|
175
|
+
</g>
|
|
176
|
+
</svg>
|
|
177
|
+
</div>
|
|
178
|
+
<div class="text text-with-icon">
|
|
179
|
+
<div class="from-doctor">${localeService.t('noteFromDoctor')} ${note.createdByName}</div>
|
|
180
|
+
<div class="note-content">${note.content.replace(/\n/g, "<br/>")}</div>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</div>`;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return doctorNotesHTML;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function renderDoctorNotesCompactView(doctorNotes, bioIndentStyle = '') {
|
|
190
|
+
let doctorNotesHTML = '';
|
|
191
|
+
if (doctorNotes && doctorNotes.length > 0) {
|
|
192
|
+
doctorNotes.forEach(note => {
|
|
193
|
+
doctorNotesHTML += `<div class="note-content">${note.content}</div>`;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return doctorNotesHTML;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function renderOneBiomarker(biomarker, isRtl, nestingLevel, isChildBiomarker, isComponent) {
|
|
200
|
+
|
|
201
|
+
let biomarkerDetailsHtml = '';
|
|
202
|
+
|
|
203
|
+
if (biomarker.showInDetailsView === true) {
|
|
204
|
+
const biomarkerCssId = "dtl-bio-" + "db" + biomarker.id;
|
|
205
|
+
let customBiomarkerValueFontSize = '';
|
|
206
|
+
const rawFormattedValue = biomarker.formattedValue || biomarker.lingualReading || '';
|
|
207
|
+
const formattedValue = rawFormattedValue.replace(/,/g, "");
|
|
208
|
+
if (formattedValue.length > 35) {
|
|
209
|
+
customBiomarkerValueFontSize = 'font-size:12px;';
|
|
210
|
+
}
|
|
211
|
+
const biomarkerName = biomarker.name || '';
|
|
212
|
+
const biomarkerStatus = biomarker.status || '';
|
|
213
|
+
const insightsCount = biomarker.insightsCount || '';
|
|
214
|
+
let CircleStyles = '';
|
|
215
|
+
if (!isComponent) {
|
|
216
|
+
CircleStyles = GetBiomarkerCircleStyle(biomarker.color, biomarkerName, biomarkerStatus, insightsCount, '', false);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Indent biomarker details based on panel level
|
|
220
|
+
let firstGridColClass = 'size5';
|
|
221
|
+
let firstGridColstyle = '';
|
|
222
|
+
let lastGridColClass = 'size3';
|
|
223
|
+
let bioIndentStyle = '';
|
|
224
|
+
let bioIndentNoteStyle = '';
|
|
225
|
+
if (nestingLevel > 0) {
|
|
226
|
+
// Replace classes
|
|
227
|
+
firstGridColClass = 'size5';
|
|
228
|
+
lastGridColClass = 'size3';
|
|
229
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
230
|
+
const levelNesting = extraPadding + nestingLevel * (INDENTATION.BIOMARKER_DETAILS || 0);
|
|
231
|
+
const levelNestingNote = extraPadding + nestingLevel * (INDENTATION.BIOMARKER_DETAILS || 0) + 16;
|
|
232
|
+
bioIndentStyle = 'padding-left: ' + levelNesting + 'px;';
|
|
233
|
+
bioIndentNoteStyle = 'padding-left: ' + levelNestingNote + 'px';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// IMC special case (large biomarker value)
|
|
237
|
+
let biomarkerClass = '';
|
|
238
|
+
if (rawFormattedValue.length >= 125) {
|
|
239
|
+
biomarkerClass = 'large-value-class';
|
|
240
|
+
firstGridColClass = '';
|
|
241
|
+
// firstGridColstyle = 'width:100%';
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const biomarkerValue = rawFormattedValue.replace(/\r\n/g, "<br/>");
|
|
245
|
+
|
|
246
|
+
if (!biomarker.showScale) {
|
|
247
|
+
biomarkerClass += ' hide-scale ';
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const biomarkerColor = (biomarker.color && !biomarker.isNormal) ? "color:" + biomarker.color + ";" : "";
|
|
251
|
+
let rangesPlaceholder = "";
|
|
252
|
+
let currentRange = "";
|
|
253
|
+
let currentPercent = 50;
|
|
254
|
+
let biomarkerTitleClass = '';
|
|
255
|
+
if (biomarker.ranges.length > 1 && biomarker.showScale) {
|
|
256
|
+
biomarkerTitleClass = 'has-ranges';
|
|
257
|
+
} else {
|
|
258
|
+
biomarkerTitleClass = 'has-no-ranges';
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
let childRangesPlaceholder = "";
|
|
262
|
+
let childCurrentRange = "";
|
|
263
|
+
let heightCount = 1;
|
|
264
|
+
let bioValue = "";
|
|
265
|
+
let bioUnit = "";
|
|
266
|
+
let afterBioInfoValue = '';
|
|
267
|
+
let History = '';
|
|
268
|
+
if (biomarker.childrenBiomarkers && biomarker.childrenBiomarkers.length > 0) {
|
|
269
|
+
biomarker.childrenBiomarkers.forEach(bio => {
|
|
270
|
+
if (bio.ranges.length > 1) {
|
|
271
|
+
heightCount++;
|
|
272
|
+
// Viewing the biomarker and unit of children after the parent ones
|
|
273
|
+
bioValue = bio.formattedValue.replace(/\n/g, "<br />");
|
|
274
|
+
let bioValue_style = "";
|
|
275
|
+
if (bioValue.length > 33) {
|
|
276
|
+
bioValue_style = "font-size:12px;";
|
|
277
|
+
}
|
|
278
|
+
bioUnit = bio.unit;
|
|
279
|
+
childCurrentRange = '';
|
|
280
|
+
// Generating the children ranges and display them under the parent ones
|
|
281
|
+
childRangesPlaceholder += '<div class="extra-range-placeholder">'
|
|
282
|
+
+ convertToRangeLayout(bio.ranges, bio, isRtl)
|
|
283
|
+
+ '</div>';
|
|
284
|
+
biomarkerTitleClass = 'has-ranges';
|
|
285
|
+
afterBioInfoValue += '<div class="colorable pair">'
|
|
286
|
+
+ '<span class="biomarker-extra-value" style="' + bioValue_style + '">' + bioValue + '</span>'
|
|
287
|
+
+ '<span class="biomarker-extra-unit">' + bioUnit + '</span>'
|
|
288
|
+
+ '</div>';
|
|
289
|
+
} else {
|
|
290
|
+
biomarkerTitleClass = 'has-no-ranges';
|
|
291
|
+
}
|
|
292
|
+
History = renderBiomarkerHistoryChart(bio);
|
|
293
|
+
});
|
|
294
|
+
} else {
|
|
295
|
+
History = renderBiomarkerHistoryChart(biomarker);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (heightCount > 1) {
|
|
299
|
+
biomarkerClass += 'hide-flag';
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Set biomarker history chart
|
|
303
|
+
const biomarkerFullName = biomarker.fullName || '';
|
|
304
|
+
let bioName = biomarkerFullName.replace(/\r\n/g, '');
|
|
305
|
+
bioName = bioName.replace(/\n/g, '');
|
|
306
|
+
const rangePlaceHolder = convertToRangeLayout(biomarker.ranges, biomarker, isRtl);
|
|
307
|
+
let biomarkerSampleHTML = '';
|
|
308
|
+
let biomInfoStyle = '';
|
|
309
|
+
let biomValueAlignStyle = '';
|
|
310
|
+
if (biomarker.sample) {
|
|
311
|
+
biomarkerSampleHTML += '<div class="biom-sample">'
|
|
312
|
+
+ '<span class="biom-sample-value">'
|
|
313
|
+
+ biomarker.sample
|
|
314
|
+
+ '</span>'
|
|
315
|
+
+ '</div>';
|
|
316
|
+
// biomValueAlignStyle = "vertical-align: bottom;";
|
|
317
|
+
}
|
|
318
|
+
if (!biomarker.sample && (rangePlaceHolder || childRangesPlaceholder || History)) {
|
|
319
|
+
biomInfoStyle = "margin-top:15px;";
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Configurations
|
|
323
|
+
let biomarkerScale = '';
|
|
324
|
+
if (isChildBiomarker) {
|
|
325
|
+
// biomarkerScale = 'transform:scale(.9);';
|
|
326
|
+
}
|
|
327
|
+
let biomCircleCss = '';
|
|
328
|
+
if (isComponent) {
|
|
329
|
+
biomCircleCss = 'opacity: 0;';
|
|
330
|
+
biomarkerSampleHTML = '';
|
|
331
|
+
bioName = '';
|
|
332
|
+
}
|
|
333
|
+
let panelNesting = '';
|
|
334
|
+
let biomarkerTitleWidth = 'width:260px';
|
|
335
|
+
if (nestingLevel > 0) {
|
|
336
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
337
|
+
const levelNesting = extraPadding + nestingLevel * (INDENTATION.PANEL_TITLE || 0);
|
|
338
|
+
panelNesting = 'padding-left: ' + levelNesting + 'px;box-sizing:border-box;';
|
|
339
|
+
const width = 260 - levelNesting;
|
|
340
|
+
biomarkerTitleWidth = 'width:' + width + 'px';
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if ((!rangePlaceHolder || !biomarker.showScale) && !childRangesPlaceholder && !History) {
|
|
344
|
+
biomarkerScale += 'width:100%;';
|
|
345
|
+
}
|
|
346
|
+
const doctorNotesArr = biomarker.doctorNotes || [];
|
|
347
|
+
const doctorNotes = renderDoctorNotes(doctorNotesArr, bioIndentNoteStyle);
|
|
348
|
+
let bioNameStyle = '';
|
|
349
|
+
let isValueNumber = !isNaN(Number(biomarkerValue));
|
|
350
|
+
let valueDataType = isValueNumber ? "number" : "string";
|
|
351
|
+
const safeBioName = bioName
|
|
352
|
+
.replace(/\(/g, '(')
|
|
353
|
+
.replace(/\)/g, ')');
|
|
354
|
+
biomarkerDetailsHtml += '<div data-id="' + biomarkerCssId + '" class="biomarker-container grid-col ' + biomarkerClass + '">'
|
|
355
|
+
+ '<div class="grid-col ' + firstGridColClass + ' ' + biomarkerClass + '" style="' + biomarkerScale + panelNesting + '">'
|
|
356
|
+
+ '<div class="biomarker">'
|
|
357
|
+
+ '<div class="biom-circle" style="' + removeWhiteSpace(CircleStyles) + ';' + biomCircleCss + '">' + biomarkerName + '</div>'
|
|
358
|
+
+ '<div class="biom-info ' + biomarkerTitleClass + '" style="' + biomInfoStyle + '">'
|
|
359
|
+
+ '<div class="title ' + biomarkerTitleClass + '" style="' + biomarkerTitleWidth + '">' + biomarkerSampleHTML + '<span class="bio-name-info b" dir="ltr" style="unicode-bidi:isolate;">' + safeBioName + '</span></div>'
|
|
360
|
+
+ '<div class="value colorable" style="' + biomValueAlignStyle + '">'
|
|
361
|
+
+ biomarkerSampleHTML
|
|
362
|
+
+ '<div class="pair parent-pair">'
|
|
363
|
+
+ '<span class="value-text" data-type="' + valueDataType + '">'
|
|
364
|
+
+ '<span style="' + customBiomarkerValueFontSize + biomarkerColor + '">' + biomarkerValue + '</span>'
|
|
365
|
+
+ '</span>'
|
|
366
|
+
+ '<span dir="ltr" class="unit colorable">' + biomarker.unit + '</span>'
|
|
367
|
+
+ '</div>'
|
|
368
|
+
+ '</div>'
|
|
369
|
+
+ afterBioInfoValue
|
|
370
|
+
+ '</div>'
|
|
371
|
+
+ '</div>'
|
|
372
|
+
+ '</div>';
|
|
373
|
+
|
|
374
|
+
if (rangePlaceHolder || childRangesPlaceholder || History) {
|
|
375
|
+
biomarkerDetailsHtml += '<div class="grid-col ' + lastGridColClass + ' ' + biomarkerClass + '" style="' + biomarkerScale + '">';
|
|
376
|
+
let biomBarClass = "";
|
|
377
|
+
if (biomarker.ranges.length > 6) {
|
|
378
|
+
biomBarClass = "big";
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
biomarkerDetailsHtml += '<div class="biom-bar ' + biomBarClass + '">';
|
|
382
|
+
}
|
|
383
|
+
if (rangePlaceHolder && biomarker.showScale) {
|
|
384
|
+
biomarkerDetailsHtml += '<div class="range-placeholder c">' + convertToRangeLayout(biomarker.ranges, biomarker, isRtl) + '</div>';
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (childRangesPlaceholder) {
|
|
388
|
+
biomarkerDetailsHtml += childRangesPlaceholder;
|
|
389
|
+
}
|
|
390
|
+
if (rangePlaceHolder || childRangesPlaceholder || History) {
|
|
391
|
+
biomarkerDetailsHtml += '</div><!-- close biom-bar -->';
|
|
392
|
+
// History chart start
|
|
393
|
+
biomarkerDetailsHtml += '<div class="grid-col history-chart-col">';
|
|
394
|
+
|
|
395
|
+
if (History) {
|
|
396
|
+
biomarkerDetailsHtml += '<div class="chart">'
|
|
397
|
+
+ History
|
|
398
|
+
+ '</div>';
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
biomarkerDetailsHtml += '</div> <!-- end chart grid col -->';
|
|
402
|
+
// History chart end
|
|
403
|
+
biomarkerDetailsHtml += '</div> <!-- close last grid-col -->';
|
|
404
|
+
}
|
|
405
|
+
if (doctorNotes) {
|
|
406
|
+
biomarkerDetailsHtml += '<div class="grid-row biomarker-insights b">'
|
|
407
|
+
+ doctorNotes
|
|
408
|
+
+ '</div>';
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
biomarkerDetailsHtml += '</div> <!-- end first close biomarker-container-->';
|
|
412
|
+
}
|
|
413
|
+
return biomarkerDetailsHtml;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function renderBiomarkerDetails(panel, isRtl, counter) {
|
|
417
|
+
let content = '';
|
|
418
|
+
panel.biomarkers.forEach((biomarker, biomarkrCounter) => {
|
|
419
|
+
content += renderOneBiomarker(biomarker, biomarkrCounter, panel, isRtl, counter);
|
|
420
|
+
});
|
|
421
|
+
return content;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function renderPanelTitle(panel, counter, biomarkrCounter) {
|
|
425
|
+
let panelTitle = '';
|
|
426
|
+
let panelSubTitle = '';
|
|
427
|
+
let content = '';
|
|
428
|
+
let checkShowInDetailsView = panel.biomarkers.find(biomarker => biomarker.showInDetailsView === true);
|
|
429
|
+
|
|
430
|
+
if (panel.biomarkers && checkShowInDetailsView && biomarkrCounter === 0) {
|
|
431
|
+
if (panel.panelDetails && panel.panelDetails.length > 1) {
|
|
432
|
+
panelTitle = panel.panelDetails[0].name;
|
|
433
|
+
let newPanelDetails = panel.panelDetails;
|
|
434
|
+
|
|
435
|
+
if (newPanelDetails.length > 0) {
|
|
436
|
+
newPanelDetails.forEach((panelDetail, index) => {
|
|
437
|
+
if (index > 0) {
|
|
438
|
+
let marginLeft = (index + 1) * 10;
|
|
439
|
+
let name = panelDetail.name ? panelDetail.name : '';
|
|
440
|
+
panelSubTitle += `<div class="panel-subtitle-item" style="padding-left:${marginLeft}px">${name}</div>`;
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
panelTitle = panel.panelDetails && panel.panelDetails[0] && panel.panelDetails[0].name ? panel.panelDetails[0].name : panel.name;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
let detailsTitle = '';
|
|
449
|
+
if (counter === 0) {
|
|
450
|
+
detailsTitle = `<div id="details-section" class="section">
|
|
451
|
+
<div class="resume-title">${localeService.t('Details')}</div>
|
|
452
|
+
</div>`;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
content += `${detailsTitle}
|
|
456
|
+
<div class="panel-title">${panelTitle}</div>
|
|
457
|
+
<div class="panel-subtitle">${panelSubTitle}</div>`;
|
|
458
|
+
}
|
|
459
|
+
return content;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function renderPanelDetails(panel, biomarkerDetailsHtml, counter, isRtl) {
|
|
463
|
+
const panelCssId = `dtl-pnl-dp${panel.panelId.toLowerCase()}`;
|
|
464
|
+
const checkShowInDetailsView = panel.biomarkers.find(biomarker => biomarker.showInDetailsView === true);
|
|
465
|
+
let detailsSectionHTML = '';
|
|
466
|
+
let panelSubTitle = '';
|
|
467
|
+
|
|
468
|
+
if (panel.biomarkers && checkShowInDetailsView) {
|
|
469
|
+
let panelTitle = panel.panelDetails && panel.panelDetails.length > 1 ? panel.panelDetails[0].name : panel.name;
|
|
470
|
+
|
|
471
|
+
if (panel.panelDetails && panel.panelDetails.length > 1) {
|
|
472
|
+
panel.panelDetails.forEach((panelDetail, index) => {
|
|
473
|
+
if (index > 0) {
|
|
474
|
+
let marginLeft = (index + 1) * 10;
|
|
475
|
+
let name = panelDetail.name ? panelDetail.name : '';
|
|
476
|
+
panelSubTitle += `<div class="panel-subtitle-item" style="padding-left:${marginLeft}px">${name}</div>`;
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
let detailsTitle = '';
|
|
482
|
+
if (counter === 0) {
|
|
483
|
+
detailsTitle = `<div id="details-section" class="section">
|
|
484
|
+
<div class="resume-title">${localeService.t('Details')}</div>
|
|
485
|
+
</div>`;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
let panelInsights = renderRelatedInsights(panel.insights, panel, true, `dtl-pnl-insight-${panel.panelId}`, isRtl);
|
|
489
|
+
let doctorNotes = renderDoctorNotes(panel.doctorNotes);
|
|
490
|
+
let bioInsights = (doctorNotes || panelInsights) ? `<div class="grid-row biomarker-insights">${doctorNotes}${panelInsights}</div>` : '';
|
|
491
|
+
|
|
492
|
+
detailsSectionHTML += `<div id="${panelCssId}" class="section panel sectionPanel">
|
|
493
|
+
<div class="panel-wrapper">
|
|
494
|
+
<div class="section-content">
|
|
495
|
+
<div class="panel-container">${biomarkerDetailsHtml}</div>
|
|
496
|
+
${bioInsights}
|
|
497
|
+
</div>
|
|
498
|
+
</div>
|
|
499
|
+
</div>`;
|
|
500
|
+
}
|
|
501
|
+
return detailsSectionHTML;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function renderOneInsight(insight, nestingLevel, isRtl) {
|
|
505
|
+
const INDENTATION = {INSIGHT: 10}; // Assuming this is defined globally
|
|
506
|
+
let insightHtml = '';
|
|
507
|
+
const insightCssId = "insight-" + "cb" + insight.id + Math.floor(Math.random() * 3);
|
|
508
|
+
let insightClass = "";
|
|
509
|
+
let content = '';
|
|
510
|
+
let tolerance = "";
|
|
511
|
+
let introductoryStatement = "";
|
|
512
|
+
let nodes = "";
|
|
513
|
+
let doctorContentClass = "hide-me";
|
|
514
|
+
let insightImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAAEgCAMAAAAjXV6yAAAAdVBMVEUAAACAma+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama/V/8ZIAAAAJnRSTlMATE389dtK6SQE7uTUOc/HlysO3qeJbwnBf1kzaBwWuZ+zYEJ1UwEot4sAAATfSURBVHja7NprcqpAEIbhDwckclPu4iUajb3/JZ78MDWQ1CmhKtKN9LOEt2bGGWwopZRSSimllFJKKaWUUkoppZRSSimllFJKKfVCFs+2vMZxelxhohx6NuMGfh4lp80trTE9Do3G5MnZecfEODQqNyqW01pHDo0tWB+OmA6HxmeSz+nsNIc4mOQwlY3mEA/3tMckOMQlbzJMgENs3I83yGcDbZxn2VXNeRv59EuyhHg20AJPlcXVh2eoKzxAuhECWWm1dqnDb6Q/0kYJZNW7bTdRUEK2kQJZ9SGiNreUvYZGC2QdC5dagk9IxhAIdelTi7+DYByBgItHLZ7kSzVPINx8alkLft4zBcI+IssUcg9qrkBYhGQFco8htkCoArISsZuML9CqdMk6S91kfIGQbckKY8jEGAjXkKwPoUuIMxA2ZPlCP32wBkpzsk4ylxBrIGzkn0K8gWKfrDMk4g304ZEVyD2G2AKhCshKxG4yvkCr0iXrLHWT8QVCtiUrjCETYyBcQ7I+hC4hzkDYkOUL/fTBGijNyTrJXEKsgbCRfwrxBop9ss6QiDfQh0dWIPcYYguEKiArEbvJ+AKtSpess9RNxhcI2ZasMIZMjIFwDcn6ELqEOANhQ5Yv9NMHa6A0J+skcwmxBsJG/inEGyj2yTpDIt5AHx5ZgdxjiC0QqoCsROwm4wu0Kl2yzlI3GV8gZFuywhgyMQbCNSTrQ+gS4gyEDVm+0E8frIHSnKyTzCXEGggb+acQb6DYJ+sMiXgDfXhkBXKPIbZAqAKyErGbjC/QqnTJOkvdZHyBkG3JCmPIxBgI15CsD6FLiDMQNmT5Qj99sAZKc7JOMpcQayBs5J9CvIFin6wzJOIN9OGRFcg9htgCoQrISsRuMr5Aq9Il6yx1k/EFQrYlK4whE2MgXEOyPoQuIc5A2JDlC/30wRoozck6yVxCrIGwkX8K8QaKfbLOkIg30IdHViD3GGILhCogKxG7yfgCrUqXrLPUTcYXCNmWrDCGTIyBcA3J+hC6hDgDYUOWL/TTB2ugNCfrJHMJsQbCRv4pxBso9sk6QyLeQB8eWYHcY4gtEKqArETsJuMLtCpdss5SNxlfIGRbssIYMjEGwjUk60PoEuIMhA1ZvtBPH6yB0pysk8wlxBoIG/mnEG+g2CfrDIl4A314ZAVyjyG2QKgCshKxm4wv0Kp0yTpL3WR8gZBtyQpjyMQYCNeQrA+hS4gzEDZk+UI/fbAGSnOyTjKXEGsgbOSfQryBYp+sMyTiDfThkRXIPYbYAqEKyErEbjK+QKvSJessdZPxBUK2JSuMIRNjIFxDsj6ELiHOQNiQ5Qv99MEaKM3JOsn+3yX0DgAAAAAAAAAAAPi3Dx06cIqm05GlAAAAAElFTkSuQmCC";
|
|
515
|
+
let insightTextClass = "";
|
|
516
|
+
let relatedBiomarkers = "";
|
|
517
|
+
|
|
518
|
+
if (insight.title) {
|
|
519
|
+
content += `<div class='title'>${insight.title}</div>`;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (insight.introductoryStatement) {
|
|
523
|
+
introductoryStatement = insight.introductoryStatement + " ";
|
|
524
|
+
} else {
|
|
525
|
+
introductoryStatement = insight.content;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
let insightCssIdStyle = '';
|
|
529
|
+
if (nestingLevel > 0) {
|
|
530
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1)
|
|
531
|
+
const levelNesting = extraPadding + nestingLevel * INDENTATION.INSIGHT;
|
|
532
|
+
insightCssIdStyle = `padding-left: ${levelNesting}px`;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function renderOneInsight(insight, nestingLevel, isRtl) {
|
|
536
|
+
const INDENTATION = {INSIGHT: 10}; // Assuming this is defined globally
|
|
537
|
+
let insightHtml = '';
|
|
538
|
+
const insightCssId = "insight-" + "cb" + insight.id.toLowerCase() + Math.floor(Math.random() * 3);
|
|
539
|
+
let insightClass = "";
|
|
540
|
+
let content = '';
|
|
541
|
+
let tolerance = "";
|
|
542
|
+
let introductoryStatement = "";
|
|
543
|
+
let nodes = "";
|
|
544
|
+
let doctorContentClass = "hide-me";
|
|
545
|
+
let insightImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAAEgCAMAAAAjXV6yAAAAdVBMVEUAAACAma+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama+Ama/V/8ZIAAAAJnRSTlMATE389dtK6SQE7uTUOc/HlysO3qeJbwnBf1kzaBwWuZ+zYEJ1UwEot4sAAATfSURBVHja7NprcqpAEIbhDwckclPu4iUajb3/JZ78MDWQ1CmhKtKN9LOEt2bGGWwopZRSSimllFJKKaWUUkoppZRSSimllFJKKfVCFs+2vMZxelxhohx6NuMGfh4lp80trTE9Do3G5MnZecfEODQqNyqW01pHDo0tWB+OmA6HxmeSz+nsNIc4mOQwlY3mEA/3tMckOMQlbzJMgENs3I83yGcDbZxn2VXNeRv59EuyhHg20AJPlcXVh2eoKzxAuhECWWm1dqnDb6Q/0kYJZNW7bTdRUEK2kQJZ9SGiNreUvYZGC2QdC5dagk9IxhAIdelTi7+DYByBgItHLZ7kSzVPINx8alkLft4zBcI+IssUcg9qrkBYhGQFco8htkCoArISsZuML9CqdMk6S91kfIGQbckKY8jEGAjXkKwPoUuIMxA2ZPlCP32wBkpzsk4ylxBrIGzkn0K8gWKfrDMk4g304ZEVyD2G2AKhCshKxG4yvkCr0iXrLHWT8QVCtiUrjCETYyBcQ7I+hC4hzkDYkOUL/fTBGijNyTrJXEKsgbCRfwrxBop9ss6QiDfQh0dWIPcYYguEKiArEbvJ+AKtSpess9RNxhcI2ZasMIZMjIFwDcn6ELqEOANhQ5Yv9NMHa6A0J+skcwmxBsJG/inEGyj2yTpDIt5AHx5ZgdxjiC0QqoCsROwm4wu0Kl2yzlI3GV8gZFuywhgyMQbCNSTrQ+gS4gyEDVm+0E8frIHSnKyTzCXEGggb+acQb6DYJ+sMiXgDfXhkBXKPIbZAqAKyErGbjC/QqnTJOkvdZHyBkG3JCmPIxBgI15CsD6FLiDMQNmT5Qj99sAZKc7JOMpcQayBs5J9CvIFin6wzJOIN9OGRFcg9htgCoQrISsRuMr5Aq9Il6yx1k/EFQrYlK4whE2MgXEOyPoQuIc5A2JDlC/30wRoozck6yVxCrIGwkX8K8QaKfbLOkIg30IdHViD3GGILhCogKxG7yfgCrUqXrLPUTcYXCNmWrDCGTIyBcA3J+hC6hDgDYUOWL/TTB2ugNCfrJHMJsQbCRv4pxBso9sk6QyLeQB8eWYHcY4gtEKqArETsJuMLtCpdss5SNxlfIGRbssIYMjEGwjUk60PoEuIMhA1ZvtBPH6yB0pysk8wlxBoIG/mnEG+g2CfrDIl4A314ZAVyjyG2QKgCshKxm4wv0Kp0yTpL3WR8gZBtyQpjyMQYCNeQrA+hS4gzEDZk+UI/fbAGSnOyTjKXEGsgbOSfQryBYp+sMyTiDfThkRXIPYbYAqEKyErEbjK+QKvSJessdZPxBUK2JSuMIRNjIFxDsj6ELiHOQNiQ5Qv99MEaKM3JOsn+3yX0DgAAAAAAAAAAAPi3Dx06cIqm05GlAAAAAElFTkSuQmCC";
|
|
546
|
+
let insightTextClass = "";
|
|
547
|
+
let relatedBiomarkers = "";
|
|
548
|
+
|
|
549
|
+
if (insight.title) {
|
|
550
|
+
content += `<div class='title'>${insight.title}</div>`;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (insight.introductoryStatement) {
|
|
554
|
+
introductoryStatement = insight.introductoryStatement + " ";
|
|
555
|
+
} else {
|
|
556
|
+
introductoryStatement = insight.content;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
let insightCssIdStyle = '';
|
|
560
|
+
if (nestingLevel > 0) {
|
|
561
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1)
|
|
562
|
+
const levelNesting = extraPadding + nestingLevel * INDENTATION.INSIGHT;
|
|
563
|
+
insightCssIdStyle = `padding-left: ${levelNesting}px`;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
if (insight.introductoryStatement || insight.summary || insight.testExplained || insight.suggestion) {
|
|
567
|
+
const introductoryStatementContent = introductoryStatement ? introductoryStatement.replace(/(\r\n|\n|\r)/gm, '') : '';
|
|
568
|
+
const insightSummaryContent = insight.summary ? insight.summary : '';
|
|
569
|
+
const testExplainedContent = insight.testExplained ? insight.testExplained : '';
|
|
570
|
+
const suggestionContent = insight.suggestion ? insight.suggestion : '';
|
|
571
|
+
content += `<div class="html-content inline-text introductory-statement">${introductoryStatementContent}</div>`;
|
|
572
|
+
content += `<div class="html-content inline-text testExplained">${testExplainedContent}</div>`;
|
|
573
|
+
content += `<div class="html-content inline-text">${insightSummaryContent}</div>`;
|
|
574
|
+
content += `<div class="html-content">${suggestionContent}</div>`;
|
|
575
|
+
|
|
576
|
+
if (isRtl) {
|
|
577
|
+
content = content.replace(/‏/g, '');
|
|
578
|
+
content = content.replace(/\(/g, '‏ <span class="ltr-dir">(');
|
|
579
|
+
content = content.replace(/\)/g, ') ‏</span>');
|
|
580
|
+
}
|
|
581
|
+
} else {
|
|
582
|
+
content += introductoryStatement;
|
|
583
|
+
if (isRtl) {
|
|
584
|
+
content = content.replace(/‏/g, '');
|
|
585
|
+
content = content.replace(/\(/g, '‏ <span class="ltr-dir">(');
|
|
586
|
+
content = content.replace(/\)/g, ') ‏</span>');
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
if (insight.detailedList) {
|
|
591
|
+
const parsedTable = parseTable(insight.detailedList);
|
|
592
|
+
nodes = renderDetails(parsedTable, isRtl);
|
|
593
|
+
doctorContentClass = "";
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (introductoryStatement) {
|
|
597
|
+
const span = "<span>";
|
|
598
|
+
if (introductoryStatement.includes(span)) {
|
|
599
|
+
tolerance = stripTags(introductoryStatement, '<span>');
|
|
600
|
+
introductoryStatement = introductoryStatement.replace(/<(.|\n)*?>/g, '');
|
|
601
|
+
introductoryStatement = introductoryStatement.replace(tolerance, '');
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
if (insight.color === "") {
|
|
606
|
+
insightClass = "tip";
|
|
607
|
+
} else {
|
|
608
|
+
insightClass = color(insight.color);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// if (insight.icon !== "") {
|
|
612
|
+
// insightImage = getFileAsBase64(insight.icon, 'image/png');
|
|
613
|
+
// }
|
|
614
|
+
|
|
615
|
+
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
616
|
+
insightTextClass = "insight-text";
|
|
617
|
+
// Loop through relatedBiomarkers and generate HTML (commented out in PHP)
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
let insightCssIdCss = '';
|
|
621
|
+
if (nestingLevel > 0) {
|
|
622
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1)
|
|
623
|
+
const levelNesting = extraPadding + nestingLevel * INDENTATION.INSIGHT + 16;
|
|
624
|
+
insightCssIdCss = `padding-left: ${levelNesting}px`;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
let svgColor = color(insight.color);
|
|
628
|
+
if (insight.isMedical) {
|
|
629
|
+
insightClass += ' medical-insight';
|
|
630
|
+
svgColor = ' medical-insight';
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
if (content || insight.disclaimer || insight.toleranceText) {
|
|
634
|
+
insightHtml += `<div id="${insightCssId}" class="card-wrapper" style="${insightCssIdCss}" insight-id="${insight.id}">
|
|
635
|
+
<div class="card insight-card a ${insightClass}">
|
|
636
|
+
<div class="insight-container">`;
|
|
637
|
+
if (insight.isMedical || insight.insightType === 'doctor-visit') {
|
|
638
|
+
insightHtml += `<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 52 52" fill="none" class="card-svg ${svgColor}">
|
|
639
|
+
<path d="M17 0C15.8955 0 15 0.895447 15 2V15H2C0.895508 15 0 15.8954 0 17V35C0 36.1046 0.895508 37 2 37H15V50C15 51.1046 15.8955 52 17 52H35C36.1045 52 37 51.1046 37 50V37H50C51.1045 37 52 36.1046 52 35V17C52 15.8954 51.1045 15 50 15H37V2C37 0.895416 36.1045 0 35 0H17Z" fill="white"/>
|
|
640
|
+
</svg>`;
|
|
641
|
+
}
|
|
642
|
+
insightHtml += `<div class="text ${insightTextClass}">${content}</div>`;
|
|
643
|
+
|
|
644
|
+
if (insight.disclaimer) {
|
|
645
|
+
insightHtml += `<div class="insight-disclaimer" style="padding: 10px 0px 0">${insight.disclaimer}</div>`;
|
|
646
|
+
}
|
|
647
|
+
if (insight.toleranceText) {
|
|
648
|
+
insightHtml += `<div class="insight-tolerance" style="padding: 10px 0px 0">${insight.toleranceText}</div>`;
|
|
649
|
+
}
|
|
650
|
+
insightHtml += `</div>`;
|
|
651
|
+
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
652
|
+
insightHtml += `<div id="${insightCssId}" class="related-icons has-related ${color(insight.color)}">${relatedBiomarkers}</div>`;
|
|
653
|
+
}
|
|
654
|
+
insightHtml += `</div></div>`;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (nodes || tolerance) {
|
|
658
|
+
insightHtml += `<div class="card-wrapper detailed-list-card-wrapper" style="${insightCssIdCss}">
|
|
659
|
+
<div class="detailed-list-wrapper">
|
|
660
|
+
<div class="detailed-list-title-wrapper">
|
|
661
|
+
<div class="doctor-only-content-container ${doctorContentClass}">
|
|
662
|
+
<h4 class="doctor-only-content-header">${getLocale('doctorContent')}</h4>
|
|
663
|
+
<span class="doctor-only-content-subheader">${getLocale('mostCommonCausesOfTheObservedValue')}</span>
|
|
664
|
+
</div>`;
|
|
665
|
+
if (nodes) {
|
|
666
|
+
insightHtml += `<ul class="detailed-list">${nodes}</ul>`;
|
|
667
|
+
}
|
|
668
|
+
if (tolerance) {
|
|
669
|
+
insightHtml += `<div class="tolerance-text">${tolerance}</div>`;
|
|
670
|
+
}
|
|
671
|
+
insightHtml += `</div></div></div>`;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return insightHtml;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
if (insight.introductoryStatement || insight.summary || insight.testExplained || insight.suggestion) {
|
|
678
|
+
const introductoryStatementContent = introductoryStatement ? introductoryStatement.replace(/(\r\n|\n|\r)/gm, '') : '';
|
|
679
|
+
const insightSummaryContent = insight.summary ? insight.summary : '';
|
|
680
|
+
const testExplainedContent = insight.testExplained ? insight.testExplained : '';
|
|
681
|
+
const suggestionContent = insight.suggestion ? insight.suggestion : '';
|
|
682
|
+
content += `<div class="html-content inline-text introductory-statement">${introductoryStatementContent}</div>`;
|
|
683
|
+
content += `<div class="html-content inline-text testExplained">${testExplainedContent}</div>`;
|
|
684
|
+
content += `<div class="html-content inline-text">${insightSummaryContent}</div>`;
|
|
685
|
+
content += `<div class="html-content">${suggestionContent}</div>`;
|
|
686
|
+
|
|
687
|
+
if (isRtl) {
|
|
688
|
+
content = content.replace(/‏/g, '');
|
|
689
|
+
content = content.replace(/\(/g, '‏ <span class="ltr-dir">(');
|
|
690
|
+
content = content.replace(/\)/g, ') ‏</span>');
|
|
691
|
+
}
|
|
692
|
+
} else {
|
|
693
|
+
content += introductoryStatement;
|
|
694
|
+
if (isRtl) {
|
|
695
|
+
content = content.replace(/‏/g, '');
|
|
696
|
+
content = content.replace(/\(/g, '‏ <span class="ltr-dir">(');
|
|
697
|
+
content = content.replace(/\)/g, ') ‏</span>');
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (insight.detailedList) {
|
|
702
|
+
const parsedTable = parseTable(insight.detailedList);
|
|
703
|
+
nodes = renderDetails(parsedTable, isRtl);
|
|
704
|
+
doctorContentClass = "";
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
if (introductoryStatement) {
|
|
708
|
+
const span = "<span>";
|
|
709
|
+
if (introductoryStatement.includes(span)) {
|
|
710
|
+
tolerance = stripTags(introductoryStatement, '<span>');
|
|
711
|
+
introductoryStatement = introductoryStatement.replace(/<(.|\n)*?>/g, '');
|
|
712
|
+
introductoryStatement = introductoryStatement.replace(tolerance, '');
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if (insight.color === "") {
|
|
717
|
+
insightClass = "tip";
|
|
718
|
+
} else {
|
|
719
|
+
insightClass = color(insight.color);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// if (insight.icon !== "") {
|
|
723
|
+
// insightImage = getFileAsBase64(insight.icon, 'image/png');
|
|
724
|
+
// }
|
|
725
|
+
|
|
726
|
+
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
727
|
+
insightTextClass = "insight-text";
|
|
728
|
+
// Loop through relatedBiomarkers and generate HTML (commented out in PHP)
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
let insightCssIdCss = '';
|
|
732
|
+
if (nestingLevel > 0) {
|
|
733
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1)
|
|
734
|
+
const levelNesting = extraPadding + nestingLevel * INDENTATION.INSIGHT + 16;
|
|
735
|
+
insightCssIdCss = `padding-left: ${levelNesting}px`;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
let svgColor = color(insight.color);
|
|
739
|
+
if (insight.isMedical) {
|
|
740
|
+
insightClass += ' medical-insight';
|
|
741
|
+
svgColor = ' medical-insight';
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
if (content || insight.disclaimer || insight.toleranceText) {
|
|
745
|
+
insightHtml += `<div id="${insightCssId}" class="card-wrapper" style="${insightCssIdCss}" insight-id="${insight.id}">
|
|
746
|
+
<div class="card insight-card a ${insightClass}">
|
|
747
|
+
<div class="insight-container">`;
|
|
748
|
+
if (insight.isMedical || insight.insightType === 'doctor-visit') {
|
|
749
|
+
insightHtml += `<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52" viewBox="0 0 52 52" fill="none" class="card-svg ${svgColor}">
|
|
750
|
+
<path d="M17 0C15.8955 0 15 0.895447 15 2V15H2C0.895508 15 0 15.8954 0 17V35C0 36.1046 0.895508 37 2 37H15V50C15 51.1046 15.8955 52 17 52H35C36.1045 52 37 51.1046 37 50V37H50C51.1045 37 52 36.1046 52 35V17C52 15.8954 51.1045 15 50 15H37V2C37 0.895416 36.1045 0 35 0H17Z" fill="white"/>
|
|
751
|
+
</svg>`;
|
|
752
|
+
}
|
|
753
|
+
insightHtml += `<div class="text ${insightTextClass}">${content}</div>`;
|
|
754
|
+
|
|
755
|
+
if (insight.disclaimer) {
|
|
756
|
+
insightHtml += `<div class="insight-disclaimer" style="padding: 10px 0px 0">${insight.disclaimer}</div>`;
|
|
757
|
+
}
|
|
758
|
+
if (insight.toleranceText) {
|
|
759
|
+
insightHtml += `<div class="insight-tolerance" style="padding: 10px 0px 0">${insight.toleranceText}</div>`;
|
|
760
|
+
}
|
|
761
|
+
insightHtml += `</div>`;
|
|
762
|
+
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
763
|
+
insightHtml += `<div id="${insightCssId}" class="related-icons has-related ${color(insight.color)}">${relatedBiomarkers}</div>`;
|
|
764
|
+
}
|
|
765
|
+
insightHtml += `</div></div>`;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
if (nodes || tolerance) {
|
|
769
|
+
insightHtml += `<div class="card-wrapper detailed-list-card-wrapper" style="${insightCssIdCss}">
|
|
770
|
+
<div class="detailed-list-wrapper">
|
|
771
|
+
<div class="detailed-list-title-wrapper">
|
|
772
|
+
<div class="doctor-only-content-container ${doctorContentClass}">
|
|
773
|
+
<h4 class="doctor-only-content-header">${getLocale('doctorContent')}</h4>
|
|
774
|
+
<span class="doctor-only-content-subheader">${getLocale('mostCommonCausesOfTheObservedValue')}</span>
|
|
775
|
+
</div>`;
|
|
776
|
+
if (nodes) {
|
|
777
|
+
insightHtml += `<ul class="detailed-list">${nodes}</ul>`;
|
|
778
|
+
}
|
|
779
|
+
if (tolerance) {
|
|
780
|
+
insightHtml += `<div class="tolerance-text">${tolerance}</div>`;
|
|
781
|
+
}
|
|
782
|
+
insightHtml += `</div></div></div>`;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
return insightHtml;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
function renderRelatedInsights(insights, panel, showRelatedBiomarkers = true, idPrefix = '', isRtl = false) {
|
|
789
|
+
let content = '';
|
|
790
|
+
if (insights.length > 0) {
|
|
791
|
+
insights.forEach((insight, insightIndex) => {
|
|
792
|
+
content += renderOneInsight(insight, insightIndex, idPrefix, panel, showRelatedBiomarkers, isRtl);
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
return content;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
function setSummaryStatInsightText(summary) {
|
|
799
|
+
let insightsHasStackedArray = [];
|
|
800
|
+
let temp2 = [...summary];
|
|
801
|
+
|
|
802
|
+
summary.forEach((summaryCheckedItem, index) => {
|
|
803
|
+
if (summaryCheckedItem.stackedInsight !== null) {
|
|
804
|
+
let test = {};
|
|
805
|
+
|
|
806
|
+
temp2.forEach((stackedElement, i) => {
|
|
807
|
+
if (stackedElement && stackedElement.id === summaryCheckedItem.stackedInsight) {
|
|
808
|
+
test.index = i;
|
|
809
|
+
summaryCheckedItem.content += `<br><br>${stackedElement.content}`;
|
|
810
|
+
test.elm = summaryCheckedItem;
|
|
811
|
+
insightsHasStackedArray[index] = stackedElement;
|
|
812
|
+
summary[test.index] = test.elm;
|
|
813
|
+
summary.splice(i, 1);
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
return summary;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
function returnSummaryTemplate(summaryI, isRtl) {
|
|
822
|
+
let summary = setSummaryStatInsightText(summaryI);
|
|
823
|
+
let insightIndex = 0;
|
|
824
|
+
let insightHtml = '';
|
|
825
|
+
|
|
826
|
+
summary.forEach(insight => {
|
|
827
|
+
let insightCssId = `smry-insight${insightIndex}`;
|
|
828
|
+
let relatedBiomarkers = '';
|
|
829
|
+
let insightCssClass = insight.isClinicalReading ? "cr" : insight.color === "" ? "tip" : color(insight.color);
|
|
830
|
+
|
|
831
|
+
let insightText = insight.title ? `<div class="title">${insight.title}</div>` : '';
|
|
832
|
+
let insightContent = insight.content;
|
|
833
|
+
|
|
834
|
+
if (isRtl) {
|
|
835
|
+
insightContent = insightContent.replace(/‏/g, '')
|
|
836
|
+
.replace(/\(/g, '‏ <span class="ltr-dir">(')
|
|
837
|
+
.replace(/\)/g, ') ‏</span>');
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
insightText += insightContent.replace(/(\r\n|\n|\r)/gm, '<br/>');
|
|
841
|
+
|
|
842
|
+
if (insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0) {
|
|
843
|
+
insight.relatedBiomarkers.forEach(item => {
|
|
844
|
+
relatedBiomarkers += GetRelatedBiomarker(
|
|
845
|
+
GetBiomarkerCircleStyle(item.color, item.name, item.status, item.insightsCount, 'nothing', true, item),
|
|
846
|
+
item.name,
|
|
847
|
+
item.fullName
|
|
848
|
+
);
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
let svgColor = color(insight.color);
|
|
853
|
+
if (insight.isMedical) {
|
|
854
|
+
insightCssClass += ' medical-insight';
|
|
855
|
+
svgColor = ' medical-insight';
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
insightHtml += `<div id="${insightCssId}" class="card insight-card ${insightCssClass}">
|
|
859
|
+
<div class="insight-container">
|
|
860
|
+
<div class="text">${insightText}</div>
|
|
861
|
+
${insight.toleranceText ? `<div class="text" style="color: #FF3200; padding: 10px 0px 5px 0px;">${insight.toleranceText}</div>` : ''}
|
|
862
|
+
</div>
|
|
863
|
+
${insight.relatedBiomarkers && insight.relatedBiomarkers.length > 0 ? `<div id="${insightCssId}" class="related-icons has-related ${color(insight.color)}">${relatedBiomarkers}</div>` : ''}
|
|
864
|
+
</div>`;
|
|
865
|
+
|
|
866
|
+
insightIndex++;
|
|
867
|
+
});
|
|
868
|
+
return insightHtml;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
function renderSummary(data, isRtl) {
|
|
872
|
+
let content = '';
|
|
873
|
+
let reportNotes = '';
|
|
874
|
+
let summary = '';
|
|
875
|
+
|
|
876
|
+
if ((data.summary) || (data.doctorNote && data.doctorNote.length > 0)) {
|
|
877
|
+
if (data.doctorNote && data.doctorNote.length > 0) {
|
|
878
|
+
reportNotes = renderDoctorNotes(data.doctorNote);
|
|
879
|
+
}
|
|
880
|
+
if (data.summary) {
|
|
881
|
+
summary = returnSummaryTemplate(data.summary, isRtl);
|
|
882
|
+
}
|
|
883
|
+
if (reportNotes && summary)
|
|
884
|
+
content += `
|
|
885
|
+
<div id="summary" class="section">
|
|
886
|
+
<div class="resume-title">${localeService.t('Summary')}</div>
|
|
887
|
+
<div class="section-content report-notes">${reportNotes}${summary}</div>
|
|
888
|
+
</div>
|
|
889
|
+
`;
|
|
890
|
+
}
|
|
891
|
+
return content;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
function renderReportSummary(data, isIMCLab) {
|
|
895
|
+
let content = '';
|
|
896
|
+
if (data.reportSummary || (data.reportProperties && !isIMCLab)) {
|
|
897
|
+
content += '<br/><br/>';
|
|
898
|
+
let reportProperties = '';
|
|
899
|
+
|
|
900
|
+
content += '<div id="report-summary" class="section">';
|
|
901
|
+
if (data.reportSummary) {
|
|
902
|
+
content += `
|
|
903
|
+
<div class="resume-title report-summary-title">${localeService.t('reportSummary')}</div>
|
|
904
|
+
<div class="section-content report-summary-content">${data.reportSummary}</div>
|
|
905
|
+
`;
|
|
906
|
+
}
|
|
907
|
+
/* add report properties */
|
|
908
|
+
if (data.reportProperties && !isIMCLab) {
|
|
909
|
+
for (const [key, value] of Object.entries(data.reportProperties)) {
|
|
910
|
+
reportProperties += `<p>${key}: ${value}</p>`;
|
|
911
|
+
}
|
|
912
|
+
content += `
|
|
913
|
+
<div class="resume-title report-properties-title">${localeService.t('reportProperties')}</div>
|
|
914
|
+
<div class="section-content report-properties-content">${reportProperties}</div>
|
|
915
|
+
`;
|
|
916
|
+
}
|
|
917
|
+
content += '</div>';
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
return content;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function renderSignature(data, isRtl, isIMCLab) {
|
|
924
|
+
let content = '';
|
|
925
|
+
let textAlign = isRtl ? 'right' : 'left';
|
|
926
|
+
|
|
927
|
+
// Lab address
|
|
928
|
+
let labAddress = '';
|
|
929
|
+
if (data.labAddress && data.labType !== 18) {
|
|
930
|
+
labAddress = data.labAddress.replace(/\n/g, "<br>");
|
|
931
|
+
}
|
|
932
|
+
content += `<td style="vertical-align: middle;"><div style="padding: 0 25px;font-size: 14px;text-align: ${textAlign};line-height: 1.4;word-break: break-all;">
|
|
933
|
+
${labAddress}
|
|
934
|
+
</div></td>`;
|
|
935
|
+
|
|
936
|
+
// Lab tel, email, and site
|
|
937
|
+
let labPhone = data.labPhoneNumber ? `${localeService.t('Tel:')} ${data.labPhoneNumber}<br/>` : '';
|
|
938
|
+
let labEmail = data.labEmailAddress ? `${localeService.t('Email:')} ${data.labEmailAddress}<br/>` : '';
|
|
939
|
+
let labSite = data.moreLink ? `${data.moreLink}<br/>` : '';
|
|
940
|
+
|
|
941
|
+
if (data.labType === 18) {
|
|
942
|
+
labSite = "Web: http://www.smartdonor.it/<br/>";
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
if (labPhone || labEmail || labSite) {
|
|
946
|
+
content += `<td style="vertical-align: middle;"><div style="width: 2px; height: 100%;background:rgba(157,169,180, 0.5);min-height: 70px "> </div></td>`;
|
|
947
|
+
}
|
|
948
|
+
content += `<td style="vertical-align: middle;"><div style="padding: 0 25px;font-size: 14px;text-align: ${textAlign};line-height: 1.4;">
|
|
949
|
+
${labPhone}
|
|
950
|
+
${labEmail}
|
|
951
|
+
${labSite}
|
|
952
|
+
</div></td>`;
|
|
953
|
+
|
|
954
|
+
if (data.labType !== 18 && !isIMCLab && (data.labStamp || (data.signatures && data.signatures.length > 0))) {
|
|
955
|
+
content += `<td style="vertical-align: middle;"><div style="width: 2px; height: 100%;background:rgba(157,169,180, 0.5);min-height: 70px"> </div></td>`;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
if (data.labType !== 18 && data.signatures && data.signatures.length > 0) {
|
|
959
|
+
data.signatures.forEach((signature, index) => {
|
|
960
|
+
let approvedBy = signature.name;
|
|
961
|
+
content += `<td style="vertical-align: middle;">
|
|
962
|
+
<div class="approved-by-doctor" style="padding: 0 25px;font-size: 14px;text-align: ${textAlign};line-height: 1.4;">
|
|
963
|
+
<div>${localeService.t('Report approved by')}</div>
|
|
964
|
+
<div>${approvedBy}</div>
|
|
965
|
+
<img class="signature-image" style="height: 50px;width: auto;" src="${signature.signatureURL}">
|
|
966
|
+
</div>
|
|
967
|
+
</td>`;
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
if (data.labStamp && data.labType !== 18) {
|
|
972
|
+
content += `<td><img class="stamp-image a" style="padding: 0 25px;align-self: center;justify-self: center;webkit-align-items:center" src="${data.labStamp}" width="100"></td>`;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
if (data.labType === 18) {
|
|
976
|
+
content += `<td><img class="stamp-image" style="float: right;padding: 0 25px;align-self: center;justify-self: center;webkit-align-items:center" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAADVCAYAAADtl80QAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAbXUAAHOgAAD83QAAg2QAAHDoAADsaAAAMD4AABCQ5OyZ6gAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAALNxJREFUeNrtXQeYVEW2np4ZZphhhiGIBAUZkkQJIohhwYyKWdeEiCKICUwYFhMgGFcFAwKKomDCgBl1FdEVFHFVQAQFBQWRIEpwhkndr477t+9u29NdVTfVvXP+7zvfvrfL3K7410l1KiODwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwdDD/wGlgtpU8FGP8wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNS0xMS0yMFQxMjo1MzoyOSswMTowMF975WEAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTUtMTEtMjBUMTI6NTM6MjkrMDE6MDAuJl3dAAAAAElFTkSuQmCC" width="100"></td>`;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
return content;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
function showDetailsView(data, isRtl) {
|
|
983
|
+
let biomarkerDetailsHtml = '';
|
|
984
|
+
let detailsSectionHTML = '';
|
|
985
|
+
let shouldShowSectionTitle = false;
|
|
986
|
+
|
|
987
|
+
data.panels.forEach((panel, counter) => {
|
|
988
|
+
/* Biomarker details template */
|
|
989
|
+
biomarkerDetailsHtml = renderBiomarkerDetails(panel, isRtl, counter);
|
|
990
|
+
|
|
991
|
+
/* Panel details template */
|
|
992
|
+
let checkShowInDetailsView = panel.biomarkers?.some(biomarker => biomarker.showInDetailsView);
|
|
993
|
+
|
|
994
|
+
if (panel.biomarkers && checkShowInDetailsView) {
|
|
995
|
+
shouldShowSectionTitle = true;
|
|
996
|
+
detailsSectionHTML += renderPanelDetails(panel, biomarkerDetailsHtml, counter, isRtl);
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
return detailsSectionHTML;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
function renderReportItems(items, isCompactView = false, isRtl = false, isRectified = false, isAllergyItem = false, allergyClasses = [], forPatient = false) {
|
|
1004
|
+
let content = '';
|
|
1005
|
+
let counter = 0;
|
|
1006
|
+
let itemCounter = 0;
|
|
1007
|
+
|
|
1008
|
+
items.forEach((dashboardItem, index) => {
|
|
1009
|
+
let nestingLevel = dashboardItem.nestingLevel;
|
|
1010
|
+
|
|
1011
|
+
if (isAllergyItem) {
|
|
1012
|
+
if (itemCounter === 0) {
|
|
1013
|
+
itemCounter++;
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
if (nestingLevel > 0) {
|
|
1017
|
+
nestingLevel -= 1;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
let showInCompactView = dashboardItem.showInCompactView || false;
|
|
1022
|
+
let showInDetailsView = dashboardItem.showInDetailsView || false;
|
|
1023
|
+
|
|
1024
|
+
if (dashboardItem.biomarker || (dashboardItem.panel && dashboardItem.panel.panelBiomarker)) {
|
|
1025
|
+
let bio = dashboardItem.biomarker || dashboardItem.panel.panelBiomarker;
|
|
1026
|
+
counter++;
|
|
1027
|
+
let indentationStyle = nestingLevel > 0 ? `margin-left:${nestingLevel * INDENTATION.BIOMARKER_DETAILS}px` : '';
|
|
1028
|
+
|
|
1029
|
+
let biomarkerContent = isAllergyItem
|
|
1030
|
+
? renderAllergyBiomarker(bio, nestingLevel, dashboardItem.isChildBiomarker, isCompactView, false, isRtl, showInDetailsView, isRectified, allergyClasses, forPatient)
|
|
1031
|
+
: renderBiomarkerV3(bio, nestingLevel, dashboardItem.isChildBiomarker, isCompactView, false, isRtl, showInDetailsView, isRectified);
|
|
1032
|
+
|
|
1033
|
+
if (counter > 1 && !isCompactView && biomarkerContent) {
|
|
1034
|
+
content += '<hr class="biomarker-container-line b">';
|
|
1035
|
+
}
|
|
1036
|
+
content += biomarkerContent;
|
|
1037
|
+
} else if (dashboardItem.panel && !dashboardItem.panel.panelBiomarker && showInCompactView && isCompactView) {
|
|
1038
|
+
content += renderPanelV3(dashboardItem.panel, nestingLevel, isCompactView, itemCounter, isRectified, isAllergyItem);
|
|
1039
|
+
} else if (dashboardItem.panel && !dashboardItem.panel.panelBiomarker && showInDetailsView && !isCompactView) {
|
|
1040
|
+
counter = 0;
|
|
1041
|
+
content += renderPanelV3(dashboardItem.panel, nestingLevel, isCompactView, itemCounter, isRectified, isAllergyItem);
|
|
1042
|
+
} else if (dashboardItem.insight && dashboardItem.showInDetailsView && !isCompactView) {
|
|
1043
|
+
content += renderOneInsight(dashboardItem.insight, nestingLevel, isRtl);
|
|
1044
|
+
} else if (dashboardItem.biomarkerAttachment) {
|
|
1045
|
+
content += renderAttachmentsV3(dashboardItem.biomarkerAttachment, nestingLevel);
|
|
1046
|
+
} else if (dashboardItem.biomarkerDetailsList) {
|
|
1047
|
+
content += renderDetailsListV3(dashboardItem.biomarkerDetailsList, nestingLevel, isCompactView);
|
|
1048
|
+
} else if (dashboardItem.biomarkerNote) {
|
|
1049
|
+
content += renderNoteV3(dashboardItem.biomarkerNote, nestingLevel, isCompactView, showInCompactView, showInDetailsView);
|
|
1050
|
+
}
|
|
1051
|
+
itemCounter++;
|
|
1052
|
+
});
|
|
1053
|
+
|
|
1054
|
+
return content;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
function renderBiomarkerV3(biomarker, nestingLevel, isChildBiomarker, isCompactView, isComponent = false, isRtl = false, showInDetailsView = true, isRectified = false) {
|
|
1058
|
+
let biomarkerCssId = `biomarker-${("db" + String(biomarker?.id ?? "")).toLowerCase()}${Math.floor(Math.random() * 3)}`;
|
|
1059
|
+
let newBiomarkerHtml = '';
|
|
1060
|
+
let biomarkerClass = '';
|
|
1061
|
+
let biomarkerParentValueStyle = '';
|
|
1062
|
+
let indentationStyle = '';
|
|
1063
|
+
|
|
1064
|
+
if (isCompactView && biomarker.showInCompactView) {
|
|
1065
|
+
let biomarkerName = biomarker.fullName || '';
|
|
1066
|
+
let biomarkerUnit = biomarker.unit;
|
|
1067
|
+
let biomarkerValue = biomarker.formattedValue || biomarker.lingualReading || '';
|
|
1068
|
+
let rangePlaceholder = '';
|
|
1069
|
+
let referenceRange = '';
|
|
1070
|
+
let biomarkerLast = '-';
|
|
1071
|
+
let biomarkerPast = '-';
|
|
1072
|
+
|
|
1073
|
+
if (shouldRenderReadingLevels(biomarker)) {
|
|
1074
|
+
rangePlaceholder = convertToMiniRangeLayout(biomarker.ranges, biomarker, isRtl);
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
if (biomarker.showScale) {
|
|
1078
|
+
let normalRangeObject = biomarker.ranges.find(range => range.isReference) || {};
|
|
1079
|
+
let formattedNormalRangeMin = normalRangeObject.formattedMinValue || null;
|
|
1080
|
+
let formattedNormalRangeMax = normalRangeObject.formattedMaxValue || null;
|
|
1081
|
+
referenceRange = biomarker.ranges.length > 1 ? getRange(biomarker) : '';
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
if (biomarker.color && !biomarker.isNormal) {
|
|
1085
|
+
biomarkerClass = 'risk';
|
|
1086
|
+
biomarkerParentValueStyle = `color:${biomarker.color};`;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
if (nestingLevel > 0) {
|
|
1090
|
+
let extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1091
|
+
let levelNesting = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS;
|
|
1092
|
+
indentationStyle = `padding-left: ${levelNesting}px`;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
if (biomarker.history && biomarker.history.length > 1) {
|
|
1096
|
+
let lastBiomarkerIndex = biomarker.history.length - 2;
|
|
1097
|
+
biomarkerLast = biomarker.history[lastBiomarkerIndex]?.formattedValue || 0;
|
|
1098
|
+
biomarkerPast = biomarker.history[lastBiomarkerIndex]?.formattedDate || '-';
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
if (biomarkerValue.length > 35) {
|
|
1102
|
+
biomarkerParentValueStyle += "font-size:12px;line-height:1";
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
let firstTdWidth = '';
|
|
1106
|
+
let tdWidth = '';
|
|
1107
|
+
if (isCompactView) {
|
|
1108
|
+
let fullPanelWidth = INDENTATION.PAGE_WIDTH;
|
|
1109
|
+
let tdCount = 7;
|
|
1110
|
+
let RectifiedTd = isRectified ? 32 : 0;
|
|
1111
|
+
tdWidth = (fullPanelWidth - RectifiedTd) / tdCount;
|
|
1112
|
+
firstTdWidth = `${tdWidth * 2}px`;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
let biomarkerNameAlign = isRtl ? 'text-align: right;' : '';
|
|
1116
|
+
const RTL_FLAG = '\u200E';
|
|
1117
|
+
|
|
1118
|
+
let isValueNumber = !isNaN(Number(biomarkerValue.replace(/\r\n/g, "<br/>")));
|
|
1119
|
+
let valueDataType = isValueNumber ? "number" : "string";
|
|
1120
|
+
let cleanBioMarkerUnit =
|
|
1121
|
+
biomarkerUnit
|
|
1122
|
+
.replace(/[\u200E\u200F\u202A-\u202E]/g, '')
|
|
1123
|
+
.replace(/\(/g, '(')
|
|
1124
|
+
.replace(/\)/g, ')');
|
|
1125
|
+
|
|
1126
|
+
newBiomarkerHtml += `<table id="${biomarkerCssId}" style="width:100%; margin: 0 auto;" class="biomarker-block biomarker-block-row ${biomarkerClass}">
|
|
1127
|
+
<tr>
|
|
1128
|
+
<td style="width:${firstTdWidth}">
|
|
1129
|
+
<div class="biom-title name" style="direction: ltr;${biomarkerNameAlign}${indentationStyle}">${biomarkerName}</div>
|
|
1130
|
+
<div class="biom-method method"></div>
|
|
1131
|
+
</td>
|
|
1132
|
+
<td class="biom-value value" style="width:max-content;">
|
|
1133
|
+
<span class="biom-parent-value value-text" data-type="${valueDataType}" style="${biomarkerParentValueStyle}">${biomarkerValue.replace(/\r\n/g, "<br/>")}</span>
|
|
1134
|
+
</td>
|
|
1135
|
+
${biomarkerUnit ?
|
|
1136
|
+
`<td class="biom-unit unit">
|
|
1137
|
+
<div class="biom-parent-unit unit-text" style="padding: 0 6px; font-family: 'Open Sans', sans-serif !important; direction: ltr !important; unicode-bidi: isolate !important;" dir="ltr">
|
|
1138
|
+
${cleanBioMarkerUnit}
|
|
1139
|
+
</div>
|
|
1140
|
+
</td>` : ''}
|
|
1141
|
+
${rangePlaceholder ? `<td class="biom-bar listing" style="width:${tdWidth}px; margin: 0;"><div class="range-placeholder b">${rangePlaceholder}</div></td>` : ''}
|
|
1142
|
+
<td class="biom-range biom-range-data" style="width:${tdWidth}px; margin: 0;"><div class="parent-reference-range range">${referenceRange}</div></td>
|
|
1143
|
+
</tr>
|
|
1144
|
+
</table>`;
|
|
1145
|
+
}
|
|
1146
|
+
// ${isRtl ?RTL_FLAG+cleanBioMarkerUnit:cleanBioMarkerUnit}
|
|
1147
|
+
if (!isCompactView && showInDetailsView) {
|
|
1148
|
+
newBiomarkerHtml += renderOneBiomarker(biomarker, isRtl, nestingLevel, isChildBiomarker, isComponent);
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
if (biomarker.components && biomarker.components.length > 0) {
|
|
1152
|
+
biomarker.components.forEach(comp => {
|
|
1153
|
+
comp.showInDetailsView = biomarker.showInDetailsView;
|
|
1154
|
+
comp.showInCompactView = biomarker.showInCompactView;
|
|
1155
|
+
comp.formattedNormalRangeMin = comp.min;
|
|
1156
|
+
comp.formattedNormalRangeMax = comp.max;
|
|
1157
|
+
newBiomarkerHtml += renderBiomarkerV3(comp, nestingLevel, isChildBiomarker, isCompactView, true, isRtl, showInDetailsView, isRectified);
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
if ((isCompactView && biomarker.showInCompactView) || (!isCompactView && biomarker.showInDetailsView)) {
|
|
1162
|
+
if (biomarker.notes && biomarker.notes.length > 0) {
|
|
1163
|
+
let BioNoteStyle = '';
|
|
1164
|
+
if (nestingLevel > 0) {
|
|
1165
|
+
let extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1166
|
+
let paddingLeft = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS + 8;
|
|
1167
|
+
BioNoteStyle = isRtl ? `padding-right:${paddingLeft}px` : `padding-left:${paddingLeft}px`;
|
|
1168
|
+
}
|
|
1169
|
+
let notesPadding = isRtl ? 'padding: 0px 16px 10px 0px;' : 'padding: 0px 0px 10px 16px;';
|
|
1170
|
+
let classNote = !isCompactView ? 'note-margin-bottom' : '';
|
|
1171
|
+
if (useMonospace) {
|
|
1172
|
+
const monoStyle = `font-style: normal; font-size: 13px; color: #333; font-family: 'Roboto Mono', monospace; white-space: pre-wrap; overflow-x: auto;`;
|
|
1173
|
+
newBiomarkerHtml += `<div class="biomarker-notes 2 ${classNote}" style="${notesPadding} ${BioNoteStyle}"><span style="${monoStyle}">${biomarker.notes.join('<br/>')}</span></div>`;
|
|
1174
|
+
} else {
|
|
1175
|
+
newBiomarkerHtml += `<div class="biomarker-notes 2 ${classNote}" style="color: #8F8F92; ${notesPadding} ${BioNoteStyle}">${biomarker.notes.join('<br/>')}</div>`;
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
return newBiomarkerHtml;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
function renderPanelV3(panel, nestingLevel, isCompactView, counter = null, isRectified = false, isAllergyItem = false) {
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
const panelCssId = `panel-${panel.panelId}db${Math.floor(Math.random() * 3)}`;
|
|
1187
|
+
const notes = panel.notes ? panel.notes.join('') : '';
|
|
1188
|
+
let classPanel = '';
|
|
1189
|
+
if (panel.doctorNotes && isCompactView) {
|
|
1190
|
+
classPanel = 'panel-with-notes';
|
|
1191
|
+
}
|
|
1192
|
+
let panelWidth = isCompactView ? 'width:687px' : '';
|
|
1193
|
+
const colspan = isCompactView ? '1' : '4';
|
|
1194
|
+
const doctorNotesCompactView = panel.doctorNotes && isCompactView
|
|
1195
|
+
? `<div class="section-content">${renderDoctorNotesCompactView(panel.doctorNotes, nestingLevel)}</div>`
|
|
1196
|
+
: '';
|
|
1197
|
+
const doctorNotesDetailsView = panel.doctorNotes && !isCompactView
|
|
1198
|
+
? `<div class="section-content-details-view">${renderDoctorNotes(panel.doctorNotes, nestingLevel)}</div>`
|
|
1199
|
+
: '';
|
|
1200
|
+
let newBiomarkerHtml = '';
|
|
1201
|
+
let panelClass = '';
|
|
1202
|
+
if (counter === 0 && !isCompactView) {
|
|
1203
|
+
panelClass = "first-panel";
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
newBiomarkerHtml += `<!--panel-->
|
|
1207
|
+
<div id="${panelCssId}" class="section panel dontend ${panelClass}">`;
|
|
1208
|
+
|
|
1209
|
+
let panelNesting = "margin-left: auto;";
|
|
1210
|
+
let panelTitleFontSize = '';
|
|
1211
|
+
if (nestingLevel > 0) {
|
|
1212
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1213
|
+
const levelNesting = extraPadding + nestingLevel * INDENTATION.PANEL_TITLE;
|
|
1214
|
+
panelWidth = INDENTATION.PAGE_WIDTH - levelNesting;
|
|
1215
|
+
panelNesting = `margin-left: ${levelNesting}px;width: ${panelWidth}px;`;
|
|
1216
|
+
panelTitleFontSize = 'font-size:18px';
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
let firstTdWidth = '';
|
|
1220
|
+
const RectifiedTd = isRectified ? 32 : 0;
|
|
1221
|
+
let tdWidth = 0; // Declare tdWidth here to make it accessible outside the if block
|
|
1222
|
+
if (isCompactView) {
|
|
1223
|
+
const fullPanelWidth = INDENTATION.PAGE_WIDTH;
|
|
1224
|
+
const tdCount = 7;
|
|
1225
|
+
|
|
1226
|
+
tdWidth = (fullPanelWidth - RectifiedTd) / tdCount;
|
|
1227
|
+
firstTdWidth = `${tdWidth * 2}px`;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
newBiomarkerHtml += `<div class="section-content-header ${classPanel}">
|
|
1231
|
+
<div class="panel-title" style="box-sizing: border-box; ${panelNesting}">
|
|
1232
|
+
<table style="width:100%; margin: 0 auto;" class="biomarker-block panel-section-header-new">
|
|
1233
|
+
<tr>`;
|
|
1234
|
+
|
|
1235
|
+
let allergyItemPanelClass = '';
|
|
1236
|
+
if (isAllergyItem && isAllergyItem) {
|
|
1237
|
+
allergyItemPanelClass = 'allergy-panel';
|
|
1238
|
+
if (panel.icon) {
|
|
1239
|
+
newBiomarkerHtml += `<td class="panel-icon-container">
|
|
1240
|
+
<img src="${panel.icon}"/>
|
|
1241
|
+
</td>`;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
newBiomarkerHtml += `<td colspan="${colspan}" style="width:${firstTdWidth}">
|
|
1246
|
+
<div class="panel-title-text ${allergyItemPanelClass}" style="${panelTitleFontSize}">${panel.name}</div>
|
|
1247
|
+
${doctorNotesCompactView}`;
|
|
1248
|
+
|
|
1249
|
+
if (notes) {
|
|
1250
|
+
newBiomarkerHtml += `<div class="panel-notes">${notes}</div>`;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
newBiomarkerHtml += `</td>`;
|
|
1254
|
+
|
|
1255
|
+
if (isCompactView) {
|
|
1256
|
+
newBiomarkerHtml += `<td class="biom-range" style="width:${tdWidth}px; margin: 0;">
|
|
1257
|
+
${localeService.t('Reference range')}
|
|
1258
|
+
</td>
|
|
1259
|
+
|
|
1260
|
+
`;
|
|
1261
|
+
if (isRectified) {
|
|
1262
|
+
newBiomarkerHtml += `<td class="biom-past" style="width:${RectifiedTd}px"></td>`;
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
newBiomarkerHtml += `</tr></table>
|
|
1267
|
+
</div>
|
|
1268
|
+
</div>
|
|
1269
|
+
${doctorNotesDetailsView}
|
|
1270
|
+
<!--panel END-->`;
|
|
1271
|
+
|
|
1272
|
+
return newBiomarkerHtml;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
function renderAttachmentsV3(attachment, nestingLevel) {
|
|
1276
|
+
if (!attachment) return '';
|
|
1277
|
+
|
|
1278
|
+
let blockStyle = '';
|
|
1279
|
+
if (nestingLevel > 0) {
|
|
1280
|
+
let extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1281
|
+
let levelNesting = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS;
|
|
1282
|
+
blockStyle = `padding-left: ${levelNesting}px`;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
let ext = attachment.split(';');
|
|
1286
|
+
if (ext[0].toLowerCase() === "data:application/pdf") {
|
|
1287
|
+
return '';
|
|
1288
|
+
} else {
|
|
1289
|
+
let pos = attachment.indexOf(';');
|
|
1290
|
+
let type = attachment.substring(0, pos).split(';');
|
|
1291
|
+
if (type[0].includes('svg')) {
|
|
1292
|
+
return `<div style="${blockStyle}" class="biomarker-attachment-item">${attachment}</div>`;
|
|
1293
|
+
} else {
|
|
1294
|
+
return `<img ${nestingLevel} style="${blockStyle};max-width:320px" class="biomarker-attachment-item" src="${attachment}" />`;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
function renderDetailsListV3(detailsList, nestingLevel, isCompactView) {
|
|
1300
|
+
let maxRowLength = -1;
|
|
1301
|
+
let content = '';
|
|
1302
|
+
let itemsCount = detailsList.map(item => item.length);
|
|
1303
|
+
let colspanColumn = Math.max(...itemsCount);
|
|
1304
|
+
|
|
1305
|
+
detailsList.forEach(row => {
|
|
1306
|
+
content += "<tr>";
|
|
1307
|
+
row.forEach(item => {
|
|
1308
|
+
let colspan = row.length === 1 ? colspanColumn : 1;
|
|
1309
|
+
content += `<td colspan="${colspan}">${item}</td>`;
|
|
1310
|
+
});
|
|
1311
|
+
|
|
1312
|
+
if (row.length > maxRowLength) {
|
|
1313
|
+
maxRowLength = row.length;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
if (row.length < maxRowLength) {
|
|
1317
|
+
content += (row.length < colspanColumn && row.length !== 1) ? fillEmptyCellsWith(maxRowLength - row.length) : '';
|
|
1318
|
+
}
|
|
1319
|
+
content += "</tr>";
|
|
1320
|
+
});
|
|
1321
|
+
|
|
1322
|
+
let blockStyle = '';
|
|
1323
|
+
let plusPadding = isCompactView ? 8 : 18;
|
|
1324
|
+
if (nestingLevel > 0) {
|
|
1325
|
+
let extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1326
|
+
let levelNesting = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS + plusPadding;
|
|
1327
|
+
blockStyle = `padding-left: ${levelNesting}px`;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
return `<div style="${blockStyle}" class="biomarker-details-table" style="padding:0 ${plusPadding}px"><table>${content}</table></div>`;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
function renderNoteV3(note, nestingLevel, isCompactView, showInCompactView, showInDetailsView) {
|
|
1334
|
+
// Standalone biomarkerNote items duplicate the note already rendered inside
|
|
1335
|
+
// renderBiomarkerV3 (biomarker.notes), so they are intentionally suppressed
|
|
1336
|
+
// here to avoid every note appearing twice. Monospace styling for PHA is
|
|
1337
|
+
// handled where biomarker.notes is rendered.
|
|
1338
|
+
return '';
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
function renderAllergyClasses(allergyClasses, isRtl = false) {
|
|
1342
|
+
let count = allergyClasses.length;
|
|
1343
|
+
let tableFloat = isRtl ? 'float: left;' : 'float: right;';
|
|
1344
|
+
let unitAlign = isRtl ? 'text-align: left;right: 0;' : 'text-align: right;left: 0;';
|
|
1345
|
+
let content = `<div class="allergy-classes-container">
|
|
1346
|
+
<span class="allergy-classes-unit" style="${unitAlign}">kU/L</span>
|
|
1347
|
+
<table class="allergy-classes-table colored" width="100%" cellspacing="0" cellpadding="0" style="${tableFloat}">
|
|
1348
|
+
<tr><td colspan="${count}" class="allergy-classes-table-title">${localeService.t('Allergy Reaction Strength')}</td></tr>`;
|
|
1349
|
+
|
|
1350
|
+
let tr1 = '<tr>';
|
|
1351
|
+
let tr2 = '<tr>';
|
|
1352
|
+
|
|
1353
|
+
allergyClasses.forEach(classItem => {
|
|
1354
|
+
let formattedMinValue = classItem.formattedMinValue;
|
|
1355
|
+
let formattedMaxValue = classItem.formattedMaxValue;
|
|
1356
|
+
let range = '';
|
|
1357
|
+
|
|
1358
|
+
if (!formattedMinValue && formattedMaxValue) {
|
|
1359
|
+
range = `< ${formattedMaxValue}`;
|
|
1360
|
+
}
|
|
1361
|
+
if (formattedMinValue && formattedMaxValue) {
|
|
1362
|
+
range = `${formattedMinValue} - ${formattedMaxValue}`;
|
|
1363
|
+
}
|
|
1364
|
+
if (formattedMinValue && !formattedMaxValue) {
|
|
1365
|
+
range = `> ${formattedMinValue}`;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
tr1 += `<td style="color:${classItem.color}">${classItem.className}</td>`;
|
|
1369
|
+
tr2 += `<td style="color:${classItem.color}">${classItem.lingualReading}<br/>${range}</td>`;
|
|
1370
|
+
});
|
|
1371
|
+
|
|
1372
|
+
tr1 += '</tr>';
|
|
1373
|
+
tr2 += '</tr>';
|
|
1374
|
+
|
|
1375
|
+
content += tr1 + tr2 + '</table></div>';
|
|
1376
|
+
return content;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
function renderAllergyBiomarker(biomarker, nestingLevel, isChildBiomarker, isCompactView, isComponent = false, isRtl = false, showInDetailsView = true, isRectified = false, allergyClasses = [], forPatient = true) {
|
|
1380
|
+
let newBiomarkerHtml = '';
|
|
1381
|
+
|
|
1382
|
+
if (!isCompactView && showInDetailsView) {
|
|
1383
|
+
newBiomarkerHtml += renderOneAllergyBiomarker(biomarker, isRtl, nestingLevel, isChildBiomarker, isComponent, allergyClasses, forPatient);
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
// Render its values inside components element
|
|
1387
|
+
if (biomarker.components && biomarker.components.length > 0) {
|
|
1388
|
+
biomarker.components.forEach(comp => {
|
|
1389
|
+
comp.showInDetailsView = biomarker.showInDetailsView;
|
|
1390
|
+
comp.showInCompactView = biomarker.showInCompactView;
|
|
1391
|
+
comp.formattedNormalRangeMin = comp.min;
|
|
1392
|
+
comp.formattedNormalRangeMax = comp.max;
|
|
1393
|
+
newBiomarkerHtml += renderAllergyBiomarker(comp, nestingLevel, isChildBiomarker, isCompactView, true, isRtl, showInDetailsView, isRectified, allergyClasses, forPatient);
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
return newBiomarkerHtml;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
function renderOneAllergyBiomarker(biomarker, isRtl, nestingLevel, isChildBiomarker, isComponent, allergyClasses, forPatient) {
|
|
1401
|
+
const INDENTATION = {
|
|
1402
|
+
BIOMARKER_DETAILS: 20, // Example value, replace with actual value
|
|
1403
|
+
PANEL_TITLE: 10 // Example value, replace with actual value
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1406
|
+
let biomarkerDetailsHtml = '';
|
|
1407
|
+
if (biomarker.showInDetailsView === true) {
|
|
1408
|
+
const biomarkerCssId = "dtl-bio-db" + String(biomarker?.id ?? "").toLowerCase();
|
|
1409
|
+
let customBiomarkerValueFontSize = '';
|
|
1410
|
+
const formattedValue = biomarker.formattedValue.replace(/,/g, "");
|
|
1411
|
+
if (formattedValue.length > 35) {
|
|
1412
|
+
customBiomarkerValueFontSize = 'font-size:12px;';
|
|
1413
|
+
}
|
|
1414
|
+
const biomarkerName = biomarker.name || '';
|
|
1415
|
+
const biomarkerStatus = biomarker.status || '';
|
|
1416
|
+
const insightsCount = biomarker.insightsCount || '';
|
|
1417
|
+
let CircleStyles = '';
|
|
1418
|
+
if (!isComponent) {
|
|
1419
|
+
CircleStyles = GetBiomarkerCircleStyle(biomarker.color, biomarkerName, biomarkerStatus, insightsCount, '', false);
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
// indent biomarker details based on panel level
|
|
1423
|
+
let firstGridColClass = 'size5';
|
|
1424
|
+
let bioIndentStyle = '';
|
|
1425
|
+
let bioIndentNoteStyle = '';
|
|
1426
|
+
if (nestingLevel > 0) {
|
|
1427
|
+
// replace classes
|
|
1428
|
+
// increase biomarker part
|
|
1429
|
+
firstGridColClass = 'size5';
|
|
1430
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1431
|
+
const levelNesting = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS;
|
|
1432
|
+
const levelNestingNote = extraPadding + nestingLevel * INDENTATION.BIOMARKER_DETAILS + 16;
|
|
1433
|
+
bioIndentStyle = 'padding-left: ' + levelNesting + 'px;';
|
|
1434
|
+
bioIndentNoteStyle = 'padding-left: ' + levelNestingNote + 'px';
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
// @note: IMC special case (large biomarker value)
|
|
1438
|
+
let biomarkerClass = '';
|
|
1439
|
+
if (biomarker.formattedValue.length >= 125) {
|
|
1440
|
+
biomarkerClass = 'large-value-class';
|
|
1441
|
+
firstGridColClass = '';
|
|
1442
|
+
//$firstGridColstyle = 'width:100%';
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
const biomarkerValue = biomarker.formattedValue.replace(/\r\n/g, "<br/>");
|
|
1446
|
+
|
|
1447
|
+
if (!biomarker.showScale) {
|
|
1448
|
+
biomarkerClass += ' hide-scale ';
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
const biomarkerColor = biomarker.color && !biomarker.isNormal ? "color:" + biomarker.color + ";" : "";
|
|
1452
|
+
let rangesPlaceholder = "";
|
|
1453
|
+
let currentRange = "";
|
|
1454
|
+
let currentPercent = 25;
|
|
1455
|
+
let biomarkerTitleClass = '';
|
|
1456
|
+
if (biomarker.ranges.length > 1) {
|
|
1457
|
+
biomarkerTitleClass = 'has-ranges';
|
|
1458
|
+
} else {
|
|
1459
|
+
biomarkerTitleClass = 'has-no-ranges';
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
let childRangesPlaceholder = "";
|
|
1463
|
+
let childCurrentRange = "";
|
|
1464
|
+
let heightCount = 1;
|
|
1465
|
+
let bioValue = "";
|
|
1466
|
+
let bioUnit = "";
|
|
1467
|
+
let afterBioInfoValue = '';
|
|
1468
|
+
let History = '';
|
|
1469
|
+
if (biomarker.childrenBiomarkers && biomarker.childrenBiomarkers.length > 0) {
|
|
1470
|
+
biomarker.childrenBiomarkers.forEach(bio => {
|
|
1471
|
+
if (bio.ranges.length > 1) {
|
|
1472
|
+
heightCount++;
|
|
1473
|
+
/* viewing the biomarker and unit of children after the parent ones */
|
|
1474
|
+
bioValue = bio.formattedValue.replace(/\n/g, "<br />");
|
|
1475
|
+
let bioValue_style = "";
|
|
1476
|
+
if (bioValue.length > 33) {
|
|
1477
|
+
bioValue_style = "font-size:12px;";
|
|
1478
|
+
}
|
|
1479
|
+
bioUnit = bio.unit;
|
|
1480
|
+
childCurrentRange = '';
|
|
1481
|
+
/* generating the children ranges and display them under the parent ones */
|
|
1482
|
+
childRangesPlaceholder += '<div class="extra-range-placeholder">'
|
|
1483
|
+
+ convertToRangeLayout(bio.ranges, bio, isRtl)
|
|
1484
|
+
+ '</div>';
|
|
1485
|
+
biomarkerTitleClass = 'has-ranges';
|
|
1486
|
+
afterBioInfoValue += '<div class="colorable pair">'
|
|
1487
|
+
+ '<span class="biomarker-extra-value" style="' + bioValue_style + '">' + bioValue + '</span>'
|
|
1488
|
+
+ '<span class="biomarker-extra-unit">' + bioUnit + '</span>'
|
|
1489
|
+
+ '</div>';
|
|
1490
|
+
} else {
|
|
1491
|
+
biomarkerTitleClass = 'has-no-ranges';
|
|
1492
|
+
}
|
|
1493
|
+
/*
|
|
1494
|
+
$History = renderBiomarkerHistoryChart($bio);
|
|
1495
|
+
*/
|
|
1496
|
+
});
|
|
1497
|
+
} else {
|
|
1498
|
+
/*
|
|
1499
|
+
$History = renderBiomarkerHistoryChart($biomarker);
|
|
1500
|
+
*/
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
if (heightCount > 1) {
|
|
1504
|
+
biomarkerClass += 'hide-flag';
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
/* set biomarker history chart */
|
|
1508
|
+
|
|
1509
|
+
const biomarkerFullName = biomarker.fullName || '';
|
|
1510
|
+
let bioName = biomarkerFullName.replace(/\r\n/g, '');
|
|
1511
|
+
bioName = bioName.replace(/\n/g, '');
|
|
1512
|
+
const rangePlaceHolder = convertToRangeLayout(biomarker.ranges, biomarker, isRtl);
|
|
1513
|
+
let biomarkerSampleHTML = '';
|
|
1514
|
+
let biomInfoStyle = '';
|
|
1515
|
+
let biomValueAlignStyle = '';
|
|
1516
|
+
if (biomarker.sample) {
|
|
1517
|
+
biomarkerSampleHTML += '<div class="biom-sample">'
|
|
1518
|
+
+ '<span class="biom-sample-value">'
|
|
1519
|
+
+ biomarker.sample
|
|
1520
|
+
+ '</span>'
|
|
1521
|
+
+ '</div>';
|
|
1522
|
+
// $biomValueAlignStyle = "vertical-align: bottom;";
|
|
1523
|
+
}
|
|
1524
|
+
if (!biomarker.sample && (rangePlaceHolder || childRangesPlaceholder || History)) {
|
|
1525
|
+
biomInfoStyle = "margin-top:15px;";
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
// Configurations
|
|
1529
|
+
let biomarkerScale = '';
|
|
1530
|
+
if (isChildBiomarker) {
|
|
1531
|
+
// $biomarkerScale = 'transform:scale(.9);';
|
|
1532
|
+
}
|
|
1533
|
+
let biomCircleCss = '';
|
|
1534
|
+
if (isComponent) {
|
|
1535
|
+
biomCircleCss = 'opacity: 0;';
|
|
1536
|
+
biomarkerSampleHTML = '';
|
|
1537
|
+
bioName = '';
|
|
1538
|
+
}
|
|
1539
|
+
let panelNesting = '';
|
|
1540
|
+
let biomarkerTitleWidth = 'width:260px';
|
|
1541
|
+
if (nestingLevel > 0) {
|
|
1542
|
+
const extraPadding = ((nestingLevel + 10 % 10) + 1);
|
|
1543
|
+
const levelNesting = extraPadding + nestingLevel * INDENTATION.PANEL_TITLE;
|
|
1544
|
+
panelNesting = isRtl ? 'padding-right: ' + levelNesting + 'px;box-sizing:border-box;' : 'padding-left: ' + levelNesting + 'px;box-sizing:border-box;';
|
|
1545
|
+
const width = 260 - levelNesting;
|
|
1546
|
+
biomarkerTitleWidth = 'width:' + width + 'px';
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
if (!rangePlaceHolder && !childRangesPlaceholder && !History) {
|
|
1550
|
+
biomarkerScale += 'width:100%;';
|
|
1551
|
+
}
|
|
1552
|
+
const doctorNotesArr = biomarker.doctorNotes || [];
|
|
1553
|
+
const doctorNotes = renderDoctorNotes(doctorNotesArr, bioIndentNoteStyle);
|
|
1554
|
+
|
|
1555
|
+
biomarkerDetailsHtml += '<div data-id="' + biomarkerCssId + '" class="allergy-biomarker-container biomarker-container grid-col ' + biomarkerClass + '">'
|
|
1556
|
+
+ '<!--panel title was her in the first biomarker -->'
|
|
1557
|
+
+ '<div class="grid-col ' + firstGridColClass + ' ' + biomarkerClass + '" style="' + biomarkerScale + panelNesting + '">'
|
|
1558
|
+
+ '<div class="biomarker">'
|
|
1559
|
+
+ '<div class="biom-circle" style="' + removeWhiteSpace(CircleStyles) + ';' + biomCircleCss + '">' + biomarkerName + '</div>'
|
|
1560
|
+
+ '<div class="biom-info ' + biomarkerTitleClass + '" style="' + biomInfoStyle + '">'
|
|
1561
|
+
+ '<div class="title ' + biomarkerTitleClass + '" style="' + biomarkerTitleWidth + '">' + biomarkerSampleHTML + '<span class="bio-name-info a" style="color: #555558;">' + bioName + '</span></div>'
|
|
1562
|
+
+ '<div class="value colorable" style="' + biomValueAlignStyle + '">'
|
|
1563
|
+
+ biomarkerSampleHTML
|
|
1564
|
+
+ '<div class="pair parent-pair">'
|
|
1565
|
+
+ '<span class="value-text">'
|
|
1566
|
+
+ '<span style="' + customBiomarkerValueFontSize + biomarkerColor + '">' + biomarkerValue + '</span>'
|
|
1567
|
+
+ '</span>'
|
|
1568
|
+
+ '<span class="unit colorable">' + biomarker.unit + '</span>'
|
|
1569
|
+
+ '</div>'
|
|
1570
|
+
+ '</div>'
|
|
1571
|
+
+ afterBioInfoValue
|
|
1572
|
+
+ '</div>'
|
|
1573
|
+
+ '</div>';
|
|
1574
|
+
|
|
1575
|
+
if (doctorNotes) {
|
|
1576
|
+
biomarkerDetailsHtml += '<div class="grid-row biomarker-insights a">'
|
|
1577
|
+
+ doctorNotes
|
|
1578
|
+
+ '</div>';
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
if (biomarker.notes && biomarker.notes.length > 0) {
|
|
1582
|
+
if (nestingLevel > 0) {
|
|
1583
|
+
// $extraPadding = (($nestingLevel + 10 % 10) + 1);
|
|
1584
|
+
// $levelNesting = $extraPadding + $nestingLevel * $INDENTATION['BIOMARKER_DETAILS'] + 5;
|
|
1585
|
+
// $bioIndentStyle = 'padding-left: ' . $levelNesting . 'px;';
|
|
1586
|
+
}
|
|
1587
|
+
bioIndentStyle = isRtl ? 'padding-right: 16px;' : 'padding-left: 16px;';
|
|
1588
|
+
|
|
1589
|
+
if (useMonospace) {
|
|
1590
|
+
const monoStyle = `font-style: normal; font-size: 13px; color: #333; font-family: 'Roboto Mono', monospace; white-space: pre-wrap; overflow-x: auto;`;
|
|
1591
|
+
biomarkerDetailsHtml += '<div class="biomarker-notes 1" style="padding-top: 10px;' + bioIndentStyle + '">';
|
|
1592
|
+
biomarkerDetailsHtml += `<span style="${monoStyle}">` + biomarker.notes.join('<br/>') + '</span>';
|
|
1593
|
+
biomarkerDetailsHtml += '</div>';
|
|
1594
|
+
} else {
|
|
1595
|
+
biomarkerDetailsHtml += '<div class="biomarker-notes 1" style="color: #8F8F92;padding-top: 10px;' + bioIndentStyle + '">';
|
|
1596
|
+
biomarkerDetailsHtml += biomarker.notes.join('<br/>');
|
|
1597
|
+
biomarkerDetailsHtml += '</div>';
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
biomarkerDetailsHtml += '</div> <!-- end first col -->';
|
|
1601
|
+
|
|
1602
|
+
if (allergyClasses) {
|
|
1603
|
+
const rangeIndex = biomarker.rangeIndex;
|
|
1604
|
+
biomarkerDetailsHtml += '<table class="allergy-classes-table" width="100%" cellspacing="0" cellpadding="0" range="' + rangeIndex + '">';
|
|
1605
|
+
|
|
1606
|
+
let tr1 = '<tr>';
|
|
1607
|
+
|
|
1608
|
+
allergyClasses.forEach((cls, index) => { // Renamed 'class' to 'cls' to avoid conflict
|
|
1609
|
+
const formattedMinValue = cls.formattedMinValue;
|
|
1610
|
+
const formattedMaxValue = cls.formattedMaxValue;
|
|
1611
|
+
let range = '';
|
|
1612
|
+
|
|
1613
|
+
if (!formattedMinValue && formattedMaxValue) {
|
|
1614
|
+
range = `< ${formattedMaxValue}`;
|
|
1615
|
+
} else if (formattedMinValue && formattedMaxValue) {
|
|
1616
|
+
range = `${formattedMinValue} - ${formattedMaxValue}`;
|
|
1617
|
+
} else if (formattedMinValue && !formattedMaxValue) {
|
|
1618
|
+
range = `> ${formattedMinValue}`;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
let value = '';
|
|
1622
|
+
|
|
1623
|
+
if (index === rangeIndex) {
|
|
1624
|
+
let currentRange = biomarker.ranges[rangeIndex];
|
|
1625
|
+
let currentPercent = 0;
|
|
1626
|
+
|
|
1627
|
+
if (currentRange.minValue !== undefined && currentRange.maxValue !== undefined) {
|
|
1628
|
+
currentPercent = ((parseFloat(biomarker.value) - currentRange.minValue) / (currentRange.maxValue - currentRange.minValue)) * 100;
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
currentPercent = Math.max(8, Math.min(77, currentPercent)); // Ensures percent is between 8 and 77
|
|
1632
|
+
const imagePlace = isRtl ? `right: ${currentPercent}%` : `left: ${currentPercent}%`;
|
|
1633
|
+
|
|
1634
|
+
value = `<span index="${rangeIndex}" class="colored-value" patient="${forPatient}" style="background:${cls.color}">`;
|
|
1635
|
+
|
|
1636
|
+
if (!forPatient) {
|
|
1637
|
+
value += biomarker.formattedValue;
|
|
1638
|
+
} else {
|
|
1639
|
+
value += `<span style="${imagePlace}" class="white-circle"></span>`;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
value += `</span>`;
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
tr1 += `<td>${value}</td>`;
|
|
1646
|
+
});
|
|
1647
|
+
allergyClasses.forEach((cls, index) => { // Renamed 'class' to 'cls' to avoid conflict
|
|
1648
|
+
const formattedMinValue = cls.formattedMinValue;
|
|
1649
|
+
const formattedMaxValue = cls.formattedMaxValue;
|
|
1650
|
+
let range = '';
|
|
1651
|
+
|
|
1652
|
+
if (!formattedMinValue && formattedMaxValue) {
|
|
1653
|
+
range = `< ${formattedMaxValue}`;
|
|
1654
|
+
} else if (formattedMinValue && formattedMaxValue) {
|
|
1655
|
+
range = `${formattedMinValue} - ${formattedMaxValue}`;
|
|
1656
|
+
} else if (formattedMinValue && !formattedMaxValue) {
|
|
1657
|
+
range = `> ${formattedMinValue}`;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
let value = '';
|
|
1661
|
+
|
|
1662
|
+
if (index === rangeIndex) {
|
|
1663
|
+
let currentRange = biomarker.ranges[rangeIndex];
|
|
1664
|
+
let currentPercent = 0;
|
|
1665
|
+
|
|
1666
|
+
if (currentRange.minValue !== undefined && currentRange.maxValue !== undefined) {
|
|
1667
|
+
currentPercent = ((parseFloat(biomarker.value) - currentRange.minValue) / (currentRange.maxValue - currentRange.minValue)) * 100;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
currentPercent = Math.max(8, Math.min(77, currentPercent)); // Ensures percent is between 8 and 77
|
|
1671
|
+
const imagePlace = isRtl ? `right: ${currentPercent}%` : `left: ${currentPercent}%`;
|
|
1672
|
+
|
|
1673
|
+
value = `<span index="${rangeIndex}" class="colored-value" patient="${forPatient}" style="background:${cls.color}">`;
|
|
1674
|
+
|
|
1675
|
+
if (!forPatient) {
|
|
1676
|
+
value += biomarker.formattedValue;
|
|
1677
|
+
} else {
|
|
1678
|
+
value += `<span style="${imagePlace}" class="white-circle"></span>`;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
value += `</span>`;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
tr1 += `<td>${value}</td>`;
|
|
1685
|
+
});
|
|
1686
|
+
|
|
1687
|
+
tr1 += '</tr>';
|
|
1688
|
+
biomarkerDetailsHtml += tr1 + '</table>';
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
biomarkerDetailsHtml += '</div> <!-- end first close biomarker-container-->';
|
|
1692
|
+
}
|
|
1693
|
+
return biomarkerDetailsHtml;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
// Helper functions (assuming they exist in your code)
|
|
1697
|
+
function GetBiomarkerCircleStyle(BiomarkerColor, BiomarkerName, BiomarkerStatus, BiomarkerInsightsCount, PanelName, isSummary, item = []) {
|
|
1698
|
+
let CircleStyles = '';
|
|
1699
|
+
let fontSize = BiomarkerName && BiomarkerName.length > 6 ? '12px' : '14px';
|
|
1700
|
+
let color = BiomarkerColor || "#555555";
|
|
1701
|
+
let BioColor = BiomarkerColor || "#E05A5A";
|
|
1702
|
+
let backgroundColor = BioColor ? 'transparent' : "#E05A5A30";
|
|
1703
|
+
|
|
1704
|
+
if (isSummary) {
|
|
1705
|
+
CircleStyles = `background-color: ${backgroundColor}; border: 2px solid ${BioColor}; color: ${color}; font-size: ${fontSize};`;
|
|
1706
|
+
} else {
|
|
1707
|
+
BioColor = BiomarkerColor || "#555555";
|
|
1708
|
+
CircleStyles = `background-color: transparent; border: 2px solid ${BioColor}; color: ${color}; font-size: ${fontSize};`;
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
if ((BiomarkerInsightsCount !== undefined && BiomarkerStatus !== undefined) || BiomarkerInsightsCount === null || BiomarkerStatus === null) {
|
|
1712
|
+
backgroundColor = (BiomarkerInsightsCount || PanelName.toLowerCase() === 'health risk calculators') ? BiomarkerColor : "transparent";
|
|
1713
|
+
let BiomarkerBorder = (BiomarkerInsightsCount || PanelName.toLowerCase() === 'health risk calculators') ? `2px solid ${BiomarkerColor}` : `2px solid ${BiomarkerColor}`;
|
|
1714
|
+
color = BiomarkerInsightsCount ? "#ffffff" : BiomarkerColor;
|
|
1715
|
+
fontSize = BiomarkerName && PanelName.toLowerCase().length > 6 ? "12px" : "14px";
|
|
1716
|
+
|
|
1717
|
+
CircleStyles = `background-color: ${backgroundColor}; border: ${BiomarkerBorder}; color: ${color}; font-size: ${fontSize};`;
|
|
1718
|
+
|
|
1719
|
+
if (BiomarkerStatus !== 1 && BiomarkerStatus !== "1") {
|
|
1720
|
+
fontSize = BiomarkerName && BiomarkerName.length > 7 ? "12px" : "14px";
|
|
1721
|
+
CircleStyles = `background-color: transparent; border: 2px solid rgba(0,0,0,.4); color: rgba(0,0,0,.4); font-size: ${fontSize};`;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
return CircleStyles;
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
function convertToRangeLayout(ranges, biomarker, isRtl) {
|
|
1728
|
+
|
|
1729
|
+
let barHTML = '';
|
|
1730
|
+
if (ranges.length > 1) {
|
|
1731
|
+
barHTML += '<table>';
|
|
1732
|
+
let tr1 = '<tr class="ranges">';
|
|
1733
|
+
let tr2 = '<tr class="labels">';
|
|
1734
|
+
let tr3 = '<tr class="values">';
|
|
1735
|
+
let currentPercent = 50;
|
|
1736
|
+
let currentRange = "";
|
|
1737
|
+
|
|
1738
|
+
ranges.forEach(range => {
|
|
1739
|
+
let isCurrentClass = range.isCurrent ? "current" : "";
|
|
1740
|
+
let labelClass = range.isCurrent ? 'colorable' : "";
|
|
1741
|
+
let rangeTitle = '';
|
|
1742
|
+
let rangeArrow = '';
|
|
1743
|
+
|
|
1744
|
+
if (range.isCurrent) {
|
|
1745
|
+
currentRange = `${range.minValue} - ${range.maxValue}`;
|
|
1746
|
+
if (range.minValue && range.maxValue) {
|
|
1747
|
+
currentPercent = (((parseFloat(biomarker.value) - range.minValue) / (range.maxValue - range.minValue)) * 100);
|
|
1748
|
+
}
|
|
1749
|
+
currentPercent = Math.min(90, currentPercent);
|
|
1750
|
+
let imagePlace = isRtl ? `padding-right:${currentPercent}%` : `padding-left:${currentPercent}%`;
|
|
1751
|
+
rangeArrow = `<img class="range-arrow-layout" style="${imagePlace}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAYAAADFw8lbAAAAAXNSR0IArs4c6QAAATBJREFUWAnNjgmOAjEQA/M0P90/23UhsdICw1w5uqSgIem2q7XWnPNT/ODYlFNdFMcHzm9VWdz+UL6qiuL2D+dfNVmc3lBuqoni9BHntoosLpsoL1VEcfmK87paFoddlInVojgcwplaJUv3YZTJVaJ0n8KZni1L52mUjdmidF7C2ZolS9dllM1ZonTdwtkeLUvHbZSE0aJ0dMFJGSVLdjeUpFGiZHfFSestS2Z3lMTeomQOwUntJUvWMJTkXqJkDcVJvytLxnCUhruiZEzBabkqy+40lKarouxOxWk7K8vOdJTGs6LsLMFpPSrL7DKU5qOizC7Fad+TZWY5isGeKDMlcCy2ZHkrg2KyJcpbKRybV1nuyqEYvYpyVxLH6inLd1kUs6co36Vx7DjlUQw5XfkFNeBu5tFKZ1EAAAAASUVORK5CYII="/>`;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
rangeTitle = getRangeBar(biomarker, range, biomarker.normalRangeType);
|
|
1755
|
+
let colorClass = color(range.color);
|
|
1756
|
+
tr1 += `<td style="background-position-x:${currentPercent}%;" class="${colorClass} ${isCurrentClass}">${rangeArrow}<div class="range colorablebg" style="background:${colorClass}"></div></td>`;
|
|
1757
|
+
tr2 += `<td class="${isCurrentClass} ${colorClass}"><span class="${labelClass}">${range.name}</span></td>`;
|
|
1758
|
+
tr3 += `<td>${rangeTitle}</td>`;
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
barHTML += tr1 + '</tr>' + tr3 + '</tr>' + tr2 + '</tr>';
|
|
1762
|
+
barHTML += '</table>';
|
|
1763
|
+
}
|
|
1764
|
+
return barHTML;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
function removeWhiteSpace(html) {
|
|
1769
|
+
html = html.replace(/\r\n/g, "");
|
|
1770
|
+
return html.replace(/>\s+</g, "><");
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
function fetchFileContents(filePath) {
|
|
1774
|
+
try {
|
|
1775
|
+
return fs.readFileSync(filePath, 'utf8');
|
|
1776
|
+
} catch (error) {
|
|
1777
|
+
console.error('Error reading file:', error);
|
|
1778
|
+
return null;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
function parseTable(string) {
|
|
1783
|
+
let levels = string.split("\n");
|
|
1784
|
+
let list = levels.map(level => {
|
|
1785
|
+
return {
|
|
1786
|
+
id: random(2, 6),
|
|
1787
|
+
content: level,
|
|
1788
|
+
sepCount: separtorsNumbers(level)
|
|
1789
|
+
};
|
|
1790
|
+
});
|
|
1791
|
+
|
|
1792
|
+
let parent = list[0].sepCount;
|
|
1793
|
+
|
|
1794
|
+
for (let i = 0; i < list.length; i++) {
|
|
1795
|
+
if (i === 0) {
|
|
1796
|
+
list[i].parent_id = "0";
|
|
1797
|
+
continue;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
if (parent === list[i].sepCount) {
|
|
1801
|
+
list[i].parent_id = "0";
|
|
1802
|
+
continue;
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
if (list[i - 1]) {
|
|
1806
|
+
if (list[i].sepCount > list[i - 1].sepCount) {
|
|
1807
|
+
list[i].parent_id = list[i - 1].id;
|
|
1808
|
+
} else if (list[i].sepCount === list[i - 1].sepCount) {
|
|
1809
|
+
list[i].parent_id = list[i - 1].parent_id;
|
|
1810
|
+
} else {
|
|
1811
|
+
list[i].parent_id = findParentId(i - 1, list[i].sepCount, list);
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
return list_to_tree(list, "0");
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
function renderDetails(list, isRtl) {
|
|
1820
|
+
if (list.length === 1 && !list[0].children) {
|
|
1821
|
+
return `<li class="1">${list[0].content.substring(list[0].sepCount)}</li>`;
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
let columns = [];
|
|
1825
|
+
let isParent = false;
|
|
1826
|
+
|
|
1827
|
+
list.forEach(child => {
|
|
1828
|
+
if (child.parent_id === "0") isParent = true;
|
|
1829
|
+
let div = '';
|
|
1830
|
+
|
|
1831
|
+
if (!child.children) {
|
|
1832
|
+
let childContent = child.content.substring(child.sepCount);
|
|
1833
|
+
childContent = childContent.replace('(', '(').replace(')', ')');
|
|
1834
|
+
|
|
1835
|
+
if (isRtl) {
|
|
1836
|
+
// Optional RTL handling here
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
div = `<li class="2">${childContent}</li>`;
|
|
1840
|
+
} else {
|
|
1841
|
+
div = `<li class="arrow-icon">${child.content.substring(child.sepCount)}</li>
|
|
1842
|
+
<ul>${renderDetails(child.children, isRtl)}</ul>`;
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
if (div) columns.push(div);
|
|
1846
|
+
});
|
|
1847
|
+
|
|
1848
|
+
return columns.length > 0 ? columns.join('') : null;
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
function GetRelatedBiomarker(biomarkerstyle, name, fullname) {
|
|
1852
|
+
let fontSize = '';
|
|
1853
|
+
if (name && fullname) {
|
|
1854
|
+
if (name.length >= 7) {
|
|
1855
|
+
fontSize = 'small-fontSize-circle';
|
|
1856
|
+
}
|
|
1857
|
+
return `<div class="related">
|
|
1858
|
+
<div class="bicon ${fontSize}" style="${biomarkerstyle}">
|
|
1859
|
+
<span class="bicon-inner">${name}</span>
|
|
1860
|
+
</div>
|
|
1861
|
+
</div>`;
|
|
1862
|
+
}
|
|
1863
|
+
return null;
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
function color(hex) {
|
|
1867
|
+
switch (hex) {
|
|
1868
|
+
case "#E05A5A":
|
|
1869
|
+
return "red";
|
|
1870
|
+
case "#EE734E":
|
|
1871
|
+
return "orange";
|
|
1872
|
+
case "#41B9D6":
|
|
1873
|
+
return "blue";
|
|
1874
|
+
case "#F7AA2E":
|
|
1875
|
+
return "yellow";
|
|
1876
|
+
case "#BC2828":
|
|
1877
|
+
return "dark-red";
|
|
1878
|
+
case "#02D9D1":
|
|
1879
|
+
case "#05B9AF":
|
|
1880
|
+
return "green";
|
|
1881
|
+
case "#0F0F0F":
|
|
1882
|
+
return "black";
|
|
1883
|
+
case "#87B7CE":
|
|
1884
|
+
return "lightblue";
|
|
1885
|
+
case "#FB7377":
|
|
1886
|
+
return "light-red";
|
|
1887
|
+
default:
|
|
1888
|
+
return hex;
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
function getRangeBar(item, level, normalRangeType = '') {
|
|
1893
|
+
|
|
1894
|
+
let range = '';
|
|
1895
|
+
let min = level.formattedMinValue;
|
|
1896
|
+
let max = level.formattedMaxValue;
|
|
1897
|
+
|
|
1898
|
+
if (item.ranges && item.ranges.length > 0) {
|
|
1899
|
+
let customBioWithTwoRangesAndNormalExist = false;
|
|
1900
|
+
if (item.isCustom && item.ranges.length === 2) {
|
|
1901
|
+
let normalRange = item.ranges.find(range => range.isReference);
|
|
1902
|
+
if (normalRange) customBioWithTwoRangesAndNormalExist = true;
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
let rangeIndex = item.ranges.findIndex(range => range.isReference);
|
|
1906
|
+
|
|
1907
|
+
let readingLevels = item.ranges;
|
|
1908
|
+
let prevItem = rangeIndex - 1;
|
|
1909
|
+
|
|
1910
|
+
if (max !== null || min !== null) {
|
|
1911
|
+
|
|
1912
|
+
if (level.isReference === true) {
|
|
1913
|
+
switch (normalRangeType) {
|
|
1914
|
+
case 0 | "0":
|
|
1915
|
+
range = min !== null && max !== null ? `${min} - ${max}` : min === null ? `<= ${max}` : `>= ${min}`;
|
|
1916
|
+
|
|
1917
|
+
if (prevItem >= 0 && readingLevels[prevItem]?.formattedMaxValue === min) {
|
|
1918
|
+
range = `> ${min}`;
|
|
1919
|
+
}
|
|
1920
|
+
break;
|
|
1921
|
+
case 1 | "1":
|
|
1922
|
+
range = `< ${max}`;
|
|
1923
|
+
break;
|
|
1924
|
+
case 2 | "2":
|
|
1925
|
+
range = `<= ${max}`;
|
|
1926
|
+
break;
|
|
1927
|
+
case 3 | "3":
|
|
1928
|
+
range = `> ${min}`;
|
|
1929
|
+
break;
|
|
1930
|
+
case 4 | "4":
|
|
1931
|
+
range = `>= ${min}`;
|
|
1932
|
+
break;
|
|
1933
|
+
}
|
|
1934
|
+
} else {
|
|
1935
|
+
range = min !== null && max !== null ? `${min} - ${max}` : min === null ? `< ${max}` : `> ${min}`;
|
|
1936
|
+
if (prevItem >= 0 && readingLevels[prevItem]?.formattedMaxValue === min) {
|
|
1937
|
+
range = `>= ${min}`;
|
|
1938
|
+
if (prevItem >= 0 && readingLevels[prevItem]?.formattedMaxValue === min) {
|
|
1939
|
+
range = `> ${min}`;
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
if (customBioWithTwoRangesAndNormalExist) {
|
|
1944
|
+
switch (normalRangeType) {
|
|
1945
|
+
case "0":
|
|
1946
|
+
range = min !== null && max !== null ? `${min} - ${max}` : min === null ? `< ${max}` : `> ${min}`;
|
|
1947
|
+
break;
|
|
1948
|
+
case "1":
|
|
1949
|
+
range = min !== null ? `>= ${min}` : range;
|
|
1950
|
+
break;
|
|
1951
|
+
case "2":
|
|
1952
|
+
range = min !== null ? `> ${min}` : range;
|
|
1953
|
+
break;
|
|
1954
|
+
case "3":
|
|
1955
|
+
range = max !== null ? `<= ${max}` : range;
|
|
1956
|
+
break;
|
|
1957
|
+
case "4":
|
|
1958
|
+
range = max !== null ? `< ${max}` : range;
|
|
1959
|
+
break;
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
return range;
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
function separtorsNumbers(string) {
|
|
1969
|
+
let last = string.lastIndexOf('#');
|
|
1970
|
+
let first = string.indexOf('#');
|
|
1971
|
+
|
|
1972
|
+
if (first !== -1 && first !== 0) {
|
|
1973
|
+
return 0;
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
let subString = string.substring(first, last + 1);
|
|
1977
|
+
let mySplits = subString.split('');
|
|
1978
|
+
let isLevel = mySplits.every(char => char === "#");
|
|
1979
|
+
|
|
1980
|
+
return isLevel ? mySplits.length : separtorsNumbers(string.substring(first, last));
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
function shouldRenderReadingLevels(biomarker, isComponentItem = false) {
|
|
1984
|
+
return biomarker && biomarker.ranges.length > 1 && (biomarker.showScale || isComponentItem);
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
function convertToMiniRangeLayout(ranges, biomarker, isRtl) {
|
|
1988
|
+
let barHTML = '';
|
|
1989
|
+
|
|
1990
|
+
if (ranges.length > 0) {
|
|
1991
|
+
barHTML += '<div class="bar">';
|
|
1992
|
+
ranges.forEach(range => {
|
|
1993
|
+
let colorClass = color(range.color);
|
|
1994
|
+
let label = range.name;
|
|
1995
|
+
let isCurrentClass = range.isCurrent ? "current" : "";
|
|
1996
|
+
let rangeTitle = `${range.minValue} - ${range.maxValue}`;
|
|
1997
|
+
let imgCurrent = '';
|
|
1998
|
+
|
|
1999
|
+
if (range.isCurrent) {
|
|
2000
|
+
let currentRange = `${range.minValue} - ${range.maxValue}`;
|
|
2001
|
+
let currentPercent = null;
|
|
2002
|
+
if (range.minValue && range.maxValue) {
|
|
2003
|
+
currentPercent = (((parseFloat(biomarker.value) - range.minValue) / (range.maxValue - range.minValue)) * 100);
|
|
2004
|
+
}
|
|
2005
|
+
currentPercent = currentPercent / 2;
|
|
2006
|
+
let imagePlace = currentPercent ? `left: ${currentPercent}%` : '';
|
|
2007
|
+
if (isRtl) {
|
|
2008
|
+
imagePlace = currentPercent ? `right: ${currentPercent}%` : '';
|
|
2009
|
+
}
|
|
2010
|
+
imgCurrent = `<img style="${imagePlace}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhBAMAAAClyt9cAAAAHlBMVEUAAAD///////////////////////////////////8kfJuVAAAACXRSTlMA8ObIrYNJLyOprz29AAAAaUlEQVQoz2OgPyg1mmRagCzQMhMIpjQgBNgkZ4KAGEIkcyYEJMAEOCShIhIwEZaZUDAFJlI5EwZg1kXCRQKgIpZwEQOoiCZcRAEqMhMOJmCqwTQH0y5M92C4GdNfmH7HCB/MMMQMZ7oDAAe/ZbNL9bq2AAAAAElFTkSuQmCC" />`;
|
|
2011
|
+
}
|
|
2012
|
+
barHTML += `<div class="segment ${colorClass} ${isCurrentClass}" style="background:${colorClass}">${imgCurrent}</div>`;
|
|
2013
|
+
});
|
|
2014
|
+
barHTML += '</div>';
|
|
2015
|
+
}
|
|
2016
|
+
return barHTML;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
function getRange(item, normalRangeKey = "isReference") {
|
|
2020
|
+
let range = '';
|
|
2021
|
+
if (item.ranges && item.ranges.length > 0) {
|
|
2022
|
+
let itemValues = item.ranges.find(range => range[normalRangeKey] === true);
|
|
2023
|
+
let rangeIndex = item.ranges.findIndex(range => range[normalRangeKey] === true);
|
|
2024
|
+
let readingLevels = item.ranges;
|
|
2025
|
+
|
|
2026
|
+
let max = itemValues?.formattedMaxValue ?? null;
|
|
2027
|
+
let min = itemValues?.formattedMinValue ?? null;
|
|
2028
|
+
let normalRangeType = item.normalRangeType;
|
|
2029
|
+
let prevItem = rangeIndex - 1;
|
|
2030
|
+
|
|
2031
|
+
if (max !== null || min !== null) {
|
|
2032
|
+
if (max !== null && min !== null) {
|
|
2033
|
+
range = `${min} - ${max}`;
|
|
2034
|
+
} else if (max !== null) {
|
|
2035
|
+
range = `< ${max}`;
|
|
2036
|
+
} else if (min !== null) {
|
|
2037
|
+
range = `> ${min}`;
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
switch (String(normalRangeType)) {
|
|
2041
|
+
case "0":
|
|
2042
|
+
if (max !== null && min !== null) {
|
|
2043
|
+
range = `${min} - ${max}`;
|
|
2044
|
+
} else if (max !== null) {
|
|
2045
|
+
range = `<= ${max}`;
|
|
2046
|
+
} else if (min !== null) {
|
|
2047
|
+
range = `>= ${min}`;
|
|
2048
|
+
}
|
|
2049
|
+
break;
|
|
2050
|
+
case "1":
|
|
2051
|
+
if (max !== null) range = `< ${max}`;
|
|
2052
|
+
break;
|
|
2053
|
+
case "2":
|
|
2054
|
+
if (max !== null) range = `<= ${max}`;
|
|
2055
|
+
break;
|
|
2056
|
+
case "3":
|
|
2057
|
+
if (min !== null) range = `> ${min}`;
|
|
2058
|
+
break;
|
|
2059
|
+
case "4":
|
|
2060
|
+
if (min !== null) range = `>= ${min}`;
|
|
2061
|
+
break;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
return range;
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
function find(array, key, value) {
|
|
2069
|
+
for (let single of array) {
|
|
2070
|
+
if (single[key] === value) {
|
|
2071
|
+
return single;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
return null;
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
function renderBiomarkerHistoryChart(biomarker) {
|
|
2078
|
+
let content = '';
|
|
2079
|
+
const history = biomarker.history && biomarker.history.length > 0 ? biomarker.history : [];
|
|
2080
|
+
|
|
2081
|
+
// Custom biomarker shouldn't have a chart
|
|
2082
|
+
if (history.length > 1) {
|
|
2083
|
+
const biomarkerCssChartId = "chart-bio-db" +
|
|
2084
|
+
Math.random().toString(36).substring(2, 8) +
|
|
2085
|
+
String(biomarker?.id ?? "").toLowerCase();
|
|
2086
|
+
content += `<canvas id="${biomarkerCssChartId}" width="100%" height="30" class="chart-canvas"></canvas>`;
|
|
2087
|
+
const dataset = [];
|
|
2088
|
+
const dataColor = [];
|
|
2089
|
+
const dataColorLabels = [];
|
|
2090
|
+
const dataLabel = [];
|
|
2091
|
+
const unit = [];
|
|
2092
|
+
const dataFormattedValues = [];
|
|
2093
|
+
|
|
2094
|
+
history.forEach((item, index) => {
|
|
2095
|
+
dataset[index] = parseInt(biomarker.type) ? parseFloat(item.value) : item.rangeIndex;
|
|
2096
|
+
dataFormattedValues[index] = item.formattedValue;
|
|
2097
|
+
dataColor[index] = item.color;
|
|
2098
|
+
dataColorLabels[index] = item.color === "#E05A5A" ? item.color : "rgba(51,51,51, 0.8)";
|
|
2099
|
+
dataLabel[index] = item.formattedDate;
|
|
2100
|
+
unit[index] = item.unit;
|
|
2101
|
+
});
|
|
2102
|
+
|
|
2103
|
+
const maxOfChart = Math.max(...dataset) + 0.5;
|
|
2104
|
+
const differenceRange = Math.max(...dataset) - Math.min(...dataset);
|
|
2105
|
+
let stepSizeNumber = 0.5;
|
|
2106
|
+
if (differenceRange > 100) {
|
|
2107
|
+
stepSizeNumber = 0;
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
content += `
|
|
2111
|
+
<script>
|
|
2112
|
+
$(document).ready(function() {
|
|
2113
|
+
function showChart() {
|
|
2114
|
+
const ctx = document.getElementById("${biomarkerCssChartId}").getContext("2d");
|
|
2115
|
+
new Chart(ctx, {
|
|
2116
|
+
type: "line",
|
|
2117
|
+
data: {
|
|
2118
|
+
labels: ${JSON.stringify(dataLabel)},
|
|
2119
|
+
datasets: [{
|
|
2120
|
+
data: ${JSON.stringify(dataset)},
|
|
2121
|
+
dataFormattedValues: ${JSON.stringify(dataFormattedValues)},
|
|
2122
|
+
pointBorderColor: "transparent",
|
|
2123
|
+
pointRadius: 6,
|
|
2124
|
+
pointBorderWidth: 2,
|
|
2125
|
+
lineTension: 0,
|
|
2126
|
+
fill: false,
|
|
2127
|
+
pointBackgroundColor: ${JSON.stringify(dataColor)},
|
|
2128
|
+
fill: false
|
|
2129
|
+
}]
|
|
2130
|
+
},
|
|
2131
|
+
options: {
|
|
2132
|
+
layout: {
|
|
2133
|
+
padding: {
|
|
2134
|
+
top: 30,
|
|
2135
|
+
bottom: 30,
|
|
2136
|
+
left: 50,
|
|
2137
|
+
right: 40
|
|
2138
|
+
}
|
|
2139
|
+
},
|
|
2140
|
+
legend: {
|
|
2141
|
+
display: false,
|
|
2142
|
+
fontColor: "black"
|
|
2143
|
+
},
|
|
2144
|
+
tooltips: { enabled: false },
|
|
2145
|
+
plugins: {
|
|
2146
|
+
datalabels: {
|
|
2147
|
+
display: "block",
|
|
2148
|
+
color: ${JSON.stringify(dataColorLabels)},
|
|
2149
|
+
align: "top",
|
|
2150
|
+
anchor: "end",
|
|
2151
|
+
clamp: true,
|
|
2152
|
+
clip: false,
|
|
2153
|
+
font: {
|
|
2154
|
+
lineHeight: 1.2,
|
|
2155
|
+
size: 12,
|
|
2156
|
+
style: "normal"
|
|
2157
|
+
},
|
|
2158
|
+
formatter: function(value, context) {
|
|
2159
|
+
return " " + context.dataset.dataFormattedValues[context.dataIndex];
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
},
|
|
2163
|
+
document: true,
|
|
2164
|
+
window: true,
|
|
2165
|
+
hover: false,
|
|
2166
|
+
beginAtZero: false,
|
|
2167
|
+
responsive: true,
|
|
2168
|
+
maintainAspectRatio: true,
|
|
2169
|
+
scales: {
|
|
2170
|
+
yAxes: [{
|
|
2171
|
+
ticks: {
|
|
2172
|
+
suggestedMax: ${maxOfChart},
|
|
2173
|
+
suggestedMin: 0,
|
|
2174
|
+
stepSize: ${stepSizeNumber}
|
|
2175
|
+
},
|
|
2176
|
+
display: false
|
|
2177
|
+
}],
|
|
2178
|
+
xAxes: [{
|
|
2179
|
+
gridLines: {
|
|
2180
|
+
display: false
|
|
2181
|
+
}
|
|
2182
|
+
}]
|
|
2183
|
+
},
|
|
2184
|
+
animation: {
|
|
2185
|
+
onComplete: function() {
|
|
2186
|
+
window.JSREPORT_READY_TO_START = true;
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
});
|
|
2191
|
+
}
|
|
2192
|
+
setTimeout(showChart, 200);
|
|
2193
|
+
});
|
|
2194
|
+
</script>
|
|
2195
|
+
`;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
return content;
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
|
|
2202
|
+
module.exports = {
|
|
2203
|
+
renderReportItems,
|
|
2204
|
+
find,
|
|
2205
|
+
renderSummary,
|
|
2206
|
+
renderReportSummary,
|
|
2207
|
+
renderHTMLTemplate,
|
|
2208
|
+
renderAllergyClasses,
|
|
2209
|
+
setUseMonospace,
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
|
|
2213
|
+
|
|
2214
|
+
|
|
2215
|
+
|
|
2216
|
+
|
|
2217
|
+
|
|
2218
|
+
|
|
2219
|
+
|
|
2220
|
+
|
|
2221
|
+
|
|
2222
|
+
|
|
2223
|
+
|
|
2224
|
+
|
|
2225
|
+
|
|
2226
|
+
|
|
2227
|
+
|