Skip to content

Commit d5d8540

Browse files
Medical information generators (#184)
* Add medical information generator and other sub types * Add cyst data display * Swap order of sections
1 parent f25fd0b commit d5d8540

File tree

21 files changed

+2850
-1201
lines changed

21 files changed

+2850
-1201
lines changed

app/assets/javascript/breast-features.js

Lines changed: 1026 additions & 1059 deletions
Large diffs are not rendered by default.

app/assets/javascript/expandable-sections.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// Handle expandable sections with completion tracking
44
document.addEventListener('DOMContentLoaded', function () {
5-
console.log('Expandable sections script loaded') // Debug log
5+
// console.log('Expandable sections script loaded') // Debug log
66
const sections = document.querySelectorAll('.js-expandable-section')
77
const completedSections = new Set()
88

@@ -121,7 +121,7 @@ document.addEventListener('DOMContentLoaded', function () {
121121
// Update progress counter
122122
updateProgress(sections, completedSections)
123123

124-
console.log('All sections marked as complete')
124+
// console.log('All sections marked as complete')
125125
})
126126
})
127127
})
@@ -223,7 +223,7 @@ function openNextIncompleteSection(currentIndex, sections, completedSections) {
223223
})
224224
}
225225

226-
console.log(`Opened next incomplete section: ${nextIncompleteSection.id}`)
226+
// console.log(`Opened next incomplete section: ${nextIncompleteSection.id}`)
227227
return // Exit once we've found and opened the next incomplete section
228228
}
229229
}
@@ -248,16 +248,16 @@ function openNextIncompleteSection(currentIndex, sections, completedSections) {
248248
})
249249
}
250250

251-
console.log(
252-
`Looped back to incomplete section: ${nextIncompleteSection.id}`
253-
)
251+
// console.log(
252+
// `Looped back to incomplete section: ${nextIncompleteSection.id}`
253+
// )
254254

255255
return // Exit once we've found and opened the incomplete section
256256
}
257257
}
258258

259259
// If we get here, all sections are complete
260-
console.log('All sections are now complete!')
260+
// console.log('All sections are now complete!')
261261
highlightCompletionButton()
262262
}
263263

@@ -352,7 +352,7 @@ function updateSectionStatus(section, statusText) {
352352
}
353353

354354
if (statusElement) {
355-
console.log('Found status element:', statusElement)
355+
// console.log('Found status element:', statusElement)
356356
statusElement.textContent = statusText
357357

358358
// Update the tag colour class based on status
@@ -371,7 +371,7 @@ function updateSectionStatus(section, statusText) {
371371
statusElement.classList.add('nhsuk-tag--yellow')
372372
}
373373

374-
console.log('Updated status to:', statusText)
374+
// console.log('Updated status to:', statusText)
375375
} else {
376376
console.error('Could not find status element for section:', sectionId)
377377
}
@@ -396,9 +396,9 @@ function updateProgress(sections, completedSections) {
396396
if (progressCurrent) progressCurrent.textContent = inProgress
397397
if (progressRemaining) progressRemaining.textContent = remaining
398398

399-
console.log(
400-
`Progress: ${completed}/${totalSections} completed, ${inProgress} in progress`
401-
)
399+
// console.log(
400+
// `Progress: ${completed}/${totalSections} completed, ${inProgress} in progress`
401+
// )
402402
}
403403

404404
// Expose function globally for use by expanded-state-tracker

app/assets/javascript/modal.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,17 @@ class AppModal {
239239

240240
// Initialize modals
241241
document.addEventListener('DOMContentLoaded', () => {
242-
console.log('Initializing modals...') // Debug log
242+
// console.log('Initializing modals...') // Debug log
243243
const modals = document.querySelectorAll('.app-modal')
244-
console.log('Found modals:', modals.length) // Debug log
244+
// console.log('Found modals:', modals.length) // Debug log
245245
modals.forEach((modal) => {
246246
modal.appModal = new AppModal(modal)
247247
})
248248
})
249249

250250
// Global functions
251251
window.openModal = function (modalId) {
252-
console.log('Opening modal via global function:', modalId) // Debug log
252+
// console.log('Opening modal via global function:', modalId) // Debug log
253253
const modal = document.getElementById(modalId)
254254
if (modal && modal.appModal) {
255255
modal.appModal.open()

app/assets/javascript/scroll-to-section.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ document.addEventListener('DOMContentLoaded', function () {
55
const urlParams = new URLSearchParams(window.location.search)
66
const scrollTo = urlParams.get('scrollTo')
77

8-
console.log("scrollTo running", scrollTo)
9-
108
if (scrollTo) {
119
const targetSection = document.getElementById(scrollTo)
1210
if (targetSection) {

app/assets/sass/components/_breast-features.scss

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
@use "nhsuk-frontend/dist/nhsuk/core/objects" as *;
77
@use "nhsuk-frontend/dist/nhsuk/core/styles/typography" as *;
88

9-
109
// Custom variables for breast features
1110
$breast-features-marker-size: 40px;
1211
$breast-features-border-width: 2px;
@@ -131,7 +130,9 @@ $breast-features-z-index-dragging: 60; // Still below sticky nav but above norma
131130
background: nhsuk-colour("white");
132131
border: 4px solid $nhsuk-link-colour;
133132
padding: $breast-features-spacing-large;
134-
padding-bottom: calc($breast-features-spacing-large - 20px); // reduce padding by margin size on buttons. Ideally this would be dynamically generated.
133+
padding-bottom: calc(
134+
$breast-features-spacing-large - 20px
135+
); // reduce padding by margin size on buttons. Ideally this would be dynamically generated.
135136
box-shadow: 0 4px 16px rgba(33, 43, 50, 0.16);
136137
z-index: $breast-features-z-index-popover;
137138
min-width: $breast-features-popover-min-width;
@@ -144,7 +145,7 @@ $breast-features-z-index-dragging: 60; // Still below sticky nav but above norma
144145

145146
// ELEMENT: Features list component
146147
.breast-features__list {
147-
margin-top: 20px;
148+
// margin-top: 20px;
148149
}
149150

150151
// ELEMENT: List header
@@ -162,7 +163,7 @@ $breast-features-z-index-dragging: 60; // Still below sticky nav but above norma
162163

163164
// ELEMENT: Clear all link
164165
.breast-features__list-clear-link {
165-
font-size: 14px;
166+
font-size: 16px;
166167
}
167168

168169
// ELEMENT: List items container
@@ -271,4 +272,4 @@ $breast-features-z-index-dragging: 60; // Still below sticky nav but above norma
271272
max-width: 90vw;
272273
padding: 20px;
273274
}
274-
}
275+
}

app/data/test-scenarios.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,24 @@ module.exports = [
5555
whenRelativeToToday: 0,
5656
status: 'event_complete',
5757
approximateTime: '9:45'
58+
},
59+
// Force 100% of all medical information types for testing
60+
medicalInformation: {
61+
probabilityOfSymptoms: 1.0,
62+
probabilityOfHRT: 1.0,
63+
probabilityOfPregnancyBreastfeeding: 1.0,
64+
probabilityOfOtherMedicalInfo: 1.0,
65+
probabilityOfBreastFeatures: 1.0,
66+
probabilityOfMedicalHistory: 1.0,
67+
forceMedicalHistoryTypes: [
68+
'breastCancer',
69+
'implantedMedicalDevice',
70+
'breastImplantsAugmentation',
71+
'mastectomyLumpectomy',
72+
'cysts',
73+
'benignLumps',
74+
'otherProcedures'
75+
]
5876
}
5977
}
6078
}

app/lib/generators/event-generator.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ const dayjs = require('dayjs')
77
const config = require('../../config')
88
const { STATUS_GROUPS, isCompleted, isFinal } = require('../utils/status')
99
const { generateMammogramImages } = require('./mammogram-generator')
10-
const { generateSymptoms } = require('./symptoms-generator')
10+
const {
11+
generateMedicalInformation
12+
} = require('./medical-information-generator')
1113
const {
1214
generateSpecialAppointment
1315
} = require('./special-appointment-generator')
@@ -241,18 +243,18 @@ const generateEvent = ({
241243
// Pretend some events have previous images requested
242244
event.hasRequestedImages = weighted.select({ true: 0.3, false: 0.7 })
243245

244-
// Generate symptoms using new structure
245-
const symptomProbability = 0.15
246-
const symptoms = generateSymptoms({
247-
probabilityOfSymptoms: symptomProbability,
248-
users
246+
// Generate medical information (symptoms, medical history, etc.)
247+
// All attributed to the user who ran the appointment
248+
const medicalInformation = generateMedicalInformation({
249+
addedByUserId: event.sessionDetails.startedBy,
250+
config: participant.config,
251+
// Allow config to override probabilities for test scenarios
252+
...(participant.config?.medicalInformation || {})
249253
})
250254

251-
// Store symptoms in new medicalInformation structure
252-
if (symptoms.length > 0) {
253-
event.medicalInformation = {
254-
symptoms
255-
}
255+
// Store medical information if any was generated
256+
if (Object.keys(medicalInformation).length > 0) {
257+
event.medicalInformation = medicalInformation
256258
}
257259
}
258260

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// app/lib/generators/medical-information-generator.js
2+
3+
const { generateSymptoms } = require('./medical-information/symptoms-generator')
4+
const { generateHRT } = require('./medical-information/hrt-generator')
5+
const {
6+
generatePregnancyAndBreastfeeding
7+
} = require('./medical-information/pregnancy-and-breastfeeding-generator')
8+
const {
9+
generateOtherMedicalInformation
10+
} = require('./medical-information/other-medical-information-generator')
11+
const {
12+
generateBreastFeatures
13+
} = require('./medical-information/breast-features-generator')
14+
const {
15+
generateMedicalHistory
16+
} = require('./medical-information/medical-history-generator')
17+
18+
/**
19+
* Generate complete medical information for an event
20+
*
21+
* All medical information is attributed to the user who ran the appointment
22+
*
23+
* @param {object} options - Generation options
24+
* @param {string} [options.addedByUserId] - User ID who collected this information (typically from sessionDetails.startedBy)
25+
* @param {number} [options.probabilityOfSymptoms=0.15] - Chance of having symptoms
26+
* @param {number} [options.probabilityOfHRT=0.30] - Chance of having HRT data
27+
* @param {number} [options.probabilityOfPregnancyBreastfeeding=0.05] - Chance of having pregnancy/breastfeeding data
28+
* @param {number} [options.probabilityOfOtherMedicalInfo=0.20] - Chance of having other medical information
29+
* @param {number} [options.probabilityOfBreastFeatures=0.15] - Chance of having breast features
30+
* @param {number} [options.probabilityOfMedicalHistory=0.50] - Chance of having medical history
31+
* @param {Array} [options.forceMedicalHistoryTypes] - Array of medical history types to force generation (e.g. ['breastCancer', 'cysts'])
32+
* @param {object} [options.config] - Participant config for overrides and forced generation
33+
* @returns {object} Complete medicalInformation object
34+
*/
35+
const generateMedicalInformation = (options = {}) => {
36+
const {
37+
addedByUserId,
38+
probabilityOfSymptoms = 0.15,
39+
probabilityOfHRT = 0.3,
40+
probabilityOfPregnancyBreastfeeding = 0.05,
41+
probabilityOfOtherMedicalInfo = 0.2,
42+
probabilityOfBreastFeatures = 0.15,
43+
probabilityOfMedicalHistory = 0.5,
44+
forceMedicalHistoryTypes,
45+
config
46+
} = options
47+
48+
const medicalInfo = {}
49+
50+
// Generate symptoms
51+
const symptoms = generateSymptoms({
52+
probabilityOfSymptoms,
53+
addedByUserId
54+
})
55+
56+
if (symptoms.length > 0) {
57+
medicalInfo.symptoms = symptoms
58+
}
59+
60+
// Generate HRT information
61+
const hrt = generateHRT({
62+
probability: probabilityOfHRT
63+
})
64+
65+
if (hrt) {
66+
medicalInfo.hrt = hrt
67+
}
68+
69+
// Generate pregnancy and breastfeeding information
70+
const pregnancyAndBreastfeeding = generatePregnancyAndBreastfeeding({
71+
probability: probabilityOfPregnancyBreastfeeding
72+
})
73+
74+
if (pregnancyAndBreastfeeding) {
75+
medicalInfo.pregnancyAndBreastfeeding = pregnancyAndBreastfeeding
76+
}
77+
78+
// Generate other medical information
79+
const otherMedicalInformation = generateOtherMedicalInformation({
80+
probability: probabilityOfOtherMedicalInfo
81+
})
82+
83+
if (otherMedicalInformation) {
84+
medicalInfo.otherMedicalInformation = otherMedicalInformation
85+
}
86+
87+
// Generate medical history
88+
const medicalHistory = generateMedicalHistory({
89+
addedByUserId,
90+
probability: probabilityOfMedicalHistory,
91+
forceMedicalHistoryTypes,
92+
config
93+
})
94+
95+
if (Object.keys(medicalHistory).length > 0) {
96+
medicalInfo.medicalHistory = medicalHistory
97+
}
98+
99+
// Generate breast features
100+
const breastFeatures = generateBreastFeatures({
101+
probabilityOfAnyFeatures: probabilityOfBreastFeatures,
102+
config
103+
})
104+
105+
if (breastFeatures && breastFeatures.length > 0) {
106+
medicalInfo.breastFeatures = breastFeatures
107+
}
108+
109+
return medicalInfo
110+
}
111+
112+
module.exports = {
113+
generateMedicalInformation
114+
}

0 commit comments

Comments
 (0)