Skip to content

Commit 0477813

Browse files
authored
Merge pull request #14137 from SORMAS-Foundation/Q2-2026-release-bugfixes
Q2 2026 release bugfixes
2 parents 69d2532 + ce45e96 commit 0477813

11 files changed

Lines changed: 119 additions & 14 deletions

File tree

sormas-api/src/main/java/de/symeda/sormas/api/person/PersonDto.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ public class PersonDto extends PseudonymizableDto implements IsPerson {
290290
Disease.POLIO,
291291
Disease.UNSPECIFIED_VHF,
292292
Disease.CORONAVIRUS,
293+
Disease.PERTUSSIS,
293294
Disease.UNDEFINED,
294295
Disease.OTHER })
295296
private DeathPlaceType deathPlaceType;
@@ -300,6 +301,7 @@ public class PersonDto extends PseudonymizableDto implements IsPerson {
300301
Disease.POLIO,
301302
Disease.UNSPECIFIED_VHF,
302303
Disease.CORONAVIRUS,
304+
Disease.PERTUSSIS,
303305
Disease.UNDEFINED,
304306
Disease.OTHER })
305307
@SensitiveData

sormas-api/src/main/java/de/symeda/sormas/api/symptoms/SymptomsDto.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,8 @@ public static SymptomsDto build() {
805805
@SymptomGrouping(SymptomGroup.OTHER)
806806
private SymptomState eyesBleeding;
807807

808-
@Diseases({})
808+
@Diseases({
809+
SALMONELLOSIS })
809810
@HideForCountriesExcept(countries = {
810811
CountryHelper.COUNTRY_CODE_LUXEMBOURG })
811812
@SymptomGrouping(SymptomGroup.OTHER)
@@ -1936,6 +1937,7 @@ public static SymptomsDto build() {
19361937
GIARDIASIS,
19371938
CRYPTOSPORIDIOSIS,
19381939
MALARIA,
1940+
SALMONELLOSIS,
19391941
SHIGELLOSIS,
19401942
UNDEFINED,
19411943
OTHER })

sormas-api/src/main/resources/captions.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2972,7 +2972,7 @@ Symptoms.meningealSigns=Meningeal Signs
29722972
Symptoms.meningoencephalitis=Meningoencephalitis
29732973
Symptoms.microcephaly=Microcephaly
29742974
Symptoms.midUpperArmCircumference=Mid-upper arm circumf. (cm)
2975-
Symptoms.musclePain=Muscle pain
2975+
Symptoms.musclePain=Myalgia
29762976
Symptoms.nausea=Nausea
29772977
Symptoms.neckStiffness=Stiff neck
29782978
Symptoms.noseBleeding=Nose bleed (epistaxis)

sormas-backend/src/main/java/de/symeda/sormas/backend/user/UserRole.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ public void setLinkedDefaultUserRole(DefaultUserRole linkedDefaultUserRole) {
181181
}
182182

183183
@ElementCollection(fetch = FetchType.LAZY)
184+
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
184185
@Enumerated(EnumType.STRING)
185186
@CollectionTable(name = TABLE_NAME_EMAIL_NOTIFICATIONS,
186187
joinColumns = @JoinColumn(name = "userrole_id", referencedColumnName = UserRole.ID, nullable = false),
@@ -197,6 +198,7 @@ public void setEmailNotificationTypes(Set<NotificationType> emailNotifications)
197198
}
198199

199200
@ElementCollection(fetch = FetchType.LAZY)
201+
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
200202
@Enumerated(EnumType.STRING)
201203
@CollectionTable(name = TABLE_NAME_SMS_NOTIFICATIONS,
202204
joinColumns = @JoinColumn(name = "userrole_id", referencedColumnName = UserRole.ID, nullable = false),

sormas-base/setup/demologinmain.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ <h2 style="color: #CCC">Click on any default user login button to access the SOR
2828

2929
var demoUsers = [
3030
{id: "logInAsSurveillanceSupervisor", name: "Surveillance Supervisor", user: "SurvSup", pass: "SurvSup"},
31-
{id: "logInAsCaseSupervisor", name: "Clinician", user: "CaseSup", pass: "CaseSup"},
31+
{id: "logInAsCaseSupervisor", name: "Case Supervisor", user: "CaseSup", pass: "CaseSup"},
3232
{id: "logInAsContactSupervisor", name: "Contact Supervisor", user: "ContSup", pass: "ContSup"},
3333
{id: "logInAsPOESupervisor", name: "POE Supervisor", user: "PoeSup", pass: "PoeSup"},
3434
{id: "logInAsLabUser", name: "Lab Officer", user: "LabOff", pass: "LabOff"},

sormas-ui/src/main/java/de/symeda/sormas/ui/caze/CaseSymptomsView.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*******************************************************************************/
1818
package de.symeda.sormas.ui.caze;
1919

20+
import de.symeda.sormas.api.Disease;
2021
import de.symeda.sormas.api.FacadeProvider;
2122
import de.symeda.sormas.api.caze.CaseDataDto;
2223
import de.symeda.sormas.ui.ControllerProvider;
@@ -48,13 +49,19 @@ protected void initView(String params) {
4849
container.setEnabled(true);
4950

5051
CaseDataDto caseDataDto = FacadeProvider.getCaseFacade().getByUuid(getCaseRef().getUuid());
51-
CaseSymptomSideViewComponent symptomSideViewComponent = new CaseSymptomSideViewComponent(caseDataDto.getDisease());
52+
53+
// #14029: the Complications side panel is not relevant for Tuberculosis; keep the layout but leave the side empty
54+
boolean showComplications = caseDataDto.getDisease() != Disease.TUBERCULOSIS;
55+
CaseSymptomSideViewComponent symptomSideViewComponent =
56+
showComplications ? new CaseSymptomSideViewComponent(caseDataDto.getDisease()) : null;
5257
caseSymptomsComponent =
5358
ControllerProvider.getCaseController().getSymptomsEditComponent(getCaseRef().getUuid(), getViewMode(), symptomSideViewComponent);
5459
LayoutWithSidePanel layout = new LayoutWithSidePanel(caseSymptomsComponent, COMPLICATIONS_LOC);
5560
container.addComponent(layout);
56-
layout.addSidePanelComponent(symptomSideViewComponent, COMPLICATIONS_LOC);
57-
symptomSideViewComponent.addStyleNames(CssStyles.SIDE_COMPONENT);
61+
if (showComplications) {
62+
layout.addSidePanelComponent(symptomSideViewComponent, COMPLICATIONS_LOC);
63+
symptomSideViewComponent.addStyleNames(CssStyles.SIDE_COMPONENT);
64+
}
5865

5966
setSubComponent(container);
6067
setEditPermission(caseSymptomsComponent);

sormas-ui/src/main/java/de/symeda/sormas/ui/clinicalcourse/HealthConditionsForm.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ protected void addFields() {
247247

248248
// compliance with treatment combobox
249249
ComboBox complianceWithTreatmentCB = addField(complianceTreatmentLayout, COMPLIANCE_WITH_TREATMENT, ComboBox.class);
250+
complianceWithTreatmentCB.setCaption(null);
250251
complianceWithTreatmentCB.setId(COMPLIANCE_WITH_TREATMENT);
251252
complianceWithTreatmentCB.addItems(ComplianceWithTreatment.values());
252253
complianceTreatmentLayout.addComponent(complianceWithTreatmentCB, COMPLIANCE_WITH_TREATMENT);

sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/customizablefield/CustomizableFieldsController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public void cloneField(CustomizableFieldMetadataDto sourceDto) {
9898

9999
TextField nameField =
100100
new TextField(I18nProperties.getPrefixCaption(CustomizableFieldMetadataDto.I18N_PREFIX, CustomizableFieldMetadataDto.NAME));
101-
nameField.setWidth(280, com.vaadin.server.Sizeable.Unit.PIXELS);
101+
nameField.setWidth(100, com.vaadin.server.Sizeable.Unit.PERCENTAGE);
102102
nameField.setRequiredIndicatorVisible(true);
103103

104104
VerticalLayout content = new VerticalLayout();
@@ -111,6 +111,7 @@ public void cloneField(CustomizableFieldMetadataDto sourceDto) {
111111
content,
112112
I18nProperties.getCaption(Captions.actionClone),
113113
I18nProperties.getCaption(Captions.actionCancel),
114+
480,
114115
result -> {
115116
if (Boolean.TRUE.equals(result)) {
116117
String newName = nameField.getValue();

sormas-ui/src/main/java/de/symeda/sormas/ui/configuration/customizablefield/CustomizableFieldsGrid.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,12 @@ public CustomizableFieldsGrid(CustomizableFieldMetadataCriteria criteria) {
7777
.setSortable(false)
7878
.setWidth(40);
7979

80-
addItemClickListener(new ShowDetailsListener<>(CLONE_COLUMN_ID, e -> ControllerProvider.getCustomizableFieldsController().cloneField(e)));
8180
addItemClickListener(
82-
new ShowDetailsListener<>(TOGGLE_ACTIVE_COLUMN_ID, e -> ControllerProvider.getCustomizableFieldsController().toggleActive(e)));
81+
new ShowDetailsListener<>(CLONE_COLUMN_ID, false, e -> ControllerProvider.getCustomizableFieldsController().cloneField(e)));
8382
addItemClickListener(
84-
new ShowDetailsListener<>(DELETE_COLUMN_ID, e -> ControllerProvider.getCustomizableFieldsController().deleteField(e.getUuid(), this)));
83+
new ShowDetailsListener<>(TOGGLE_ACTIVE_COLUMN_ID, false, e -> ControllerProvider.getCustomizableFieldsController().toggleActive(e)));
84+
addItemClickListener(
85+
new ShowDetailsListener<>(DELETE_COLUMN_ID, false, e -> ControllerProvider.getCustomizableFieldsController().deleteField(e.getUuid(), this)));
8586

8687
for (Column<?, ?> column : getColumns()) {
8788
column.setCaption(I18nProperties.getPrefixCaption(CustomizableFieldMetadataDto.I18N_PREFIX, column.getId(), column.getCaption()));

sormas-ui/src/main/java/de/symeda/sormas/ui/contact/ContactCreateForm.java

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@
5151
import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto;
5252
import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto;
5353
import de.symeda.sormas.api.person.PersonDto;
54+
import de.symeda.sormas.api.therapy.Drug;
5455
import de.symeda.sormas.api.utils.DataHelper;
56+
import de.symeda.sormas.api.utils.Diseases;
5557
import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers;
5658
import de.symeda.sormas.ui.ControllerProvider;
5759
import de.symeda.sormas.ui.UiUtil;
@@ -74,6 +76,7 @@ public class ContactCreateForm extends AbstractEditForm<ContactDto> {
7476
private static final String CHOOSE_CASE_LOC = "chooseCaseLoc";
7577
private static final String REMOVE_CASE_LOC = "removeCaseLoc";
7678
private static final String ADOPT_ADDRESS_LOC = "adoptAddressLoc";
79+
private static final String PROPHYLAXIS_LOC = "prophylaxisLoc";
7780

7881
//@formatter:off
7982
private static final String HTML_LAYOUT =
@@ -97,7 +100,9 @@ public class ContactCreateForm extends AbstractEditForm<ContactDto> {
97100
LayoutUtil.fluidRowLocs(ContactDto.RELATION_TO_CASE) +
98101
LayoutUtil.fluidRowLocs(ADOPT_ADDRESS_LOC) +
99102
LayoutUtil.fluidRowLocs(ContactDto.RELATION_DESCRIPTION) +
100-
LayoutUtil.fluidRowLocs(ContactDto.DESCRIPTION);
103+
LayoutUtil.fluidRowLocs(ContactDto.DESCRIPTION) +
104+
LayoutUtil.loc(PROPHYLAXIS_LOC) +
105+
LayoutUtil.fluidRowLocs(4, ContactDto.PROPHYLAXIS_PRESCRIBED, 4, ContactDto.PRESCRIBED_DRUG, 4, ContactDto.PRESCRIBED_DRUG_TEXT);
101106
//@formatter:on
102107

103108
private OptionGroup contactProximities;
@@ -109,6 +114,7 @@ public class ContactCreateForm extends AbstractEditForm<ContactDto> {
109114
private TextField contactProximityDetails;
110115

111116
private PersonCreateForm personCreateForm;
117+
private Label prophylaxisLabel;
112118

113119
DateField reportDate;
114120
CheckBox multiDayContact;
@@ -234,6 +240,17 @@ protected void addFields() {
234240
addField(ContactDto.CASE_ID_EXTERNAL_SYSTEM, TextField.class);
235241
addField(ContactDto.CASE_OR_EVENT_INFORMATION, TextArea.class).setRows(4);
236242

243+
// Prophylaxis details for IMI (Luxembourg only) - mirrors ContactDataForm
244+
prophylaxisLabel = new Label(I18nProperties.getString(Strings.headingProphylaxisLoc));
245+
prophylaxisLabel.addStyleName(CssStyles.H3);
246+
getContent().addComponent(prophylaxisLabel, PROPHYLAXIS_LOC);
247+
prophylaxisLabel.setVisible(Disease.INVASIVE_MENINGOCOCCAL_INFECTION == disease);
248+
249+
CheckBox prophylaxisPrescribed = addField(ContactDto.PROPHYLAXIS_PRESCRIBED, CheckBox.class);
250+
prophylaxisPrescribed.setCaption(I18nProperties.getCaption(Captions.Contact_prophylaxisPrescribed));
251+
addField(ContactDto.PRESCRIBED_DRUG, ComboBox.class);
252+
addField(ContactDto.PRESCRIBED_DRUG_TEXT, TextField.class);
253+
237254
initializeVisibilitiesAndAllowedVisibilities();
238255

239256
region.addValueChangeListener(e -> {
@@ -259,14 +276,35 @@ protected void addFields() {
259276
FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.DISEASE_DETAILS, ContactDto.DISEASE, Arrays.asList(Disease.OTHER), true);
260277
FieldHelper.setRequiredWhen(getFieldGroup(), ContactDto.DISEASE, Arrays.asList(ContactDto.DISEASE_DETAILS), Arrays.asList(Disease.OTHER));
261278

279+
FieldHelper.setVisibleWhen(
280+
getFieldGroup(),
281+
ContactDto.PRESCRIBED_DRUG,
282+
ContactDto.PROPHYLAXIS_PRESCRIBED,
283+
Collections.singletonList(Boolean.TRUE),
284+
true);
285+
FieldHelper.setRequiredWhenNotNull(getFieldGroup(), ContactDto.PROPHYLAXIS_PRESCRIBED, ContactDto.PRESCRIBED_DRUG);
286+
FieldHelper.setVisibleWhen(
287+
getFieldGroup(),
288+
ContactDto.PRESCRIBED_DRUG_TEXT,
289+
ContactDto.PRESCRIBED_DRUG,
290+
Collections.singletonList(Drug.OTHER),
291+
true);
292+
FieldHelper.setRequiredWhen(
293+
getFieldGroup(),
294+
ContactDto.PRESCRIBED_DRUG,
295+
Arrays.asList(ContactDto.PRESCRIBED_DRUG_TEXT),
296+
Arrays.asList(Drug.OTHER));
297+
262298
cbDisease.addValueChangeListener(e -> {
263299
disease = (Disease) e.getProperty().getValue();
264300
setVisible(disease != null, ContactDto.CONTACT_PROXIMITIES);
265301
if (isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY)) {
266302
setVisible(disease == Disease.CORONAVIRUS, ContactDto.CONTACT_CATEGORY, ContactDto.CONTACT_PROXIMITY_DETAILS);
267303
}
268304
updateContactProximity();
305+
updateProphylaxisSectionVisibility();
269306
});
307+
updateProphylaxisSectionVisibility();
270308

271309
if (!hasCaseRelation) {
272310
Label caseInfoLabel = new Label(I18nProperties.getString(Strings.infoNoSourceCaseSelected), ContentMode.HTML);
@@ -379,6 +417,44 @@ private void updateContactProximity() {
379417
contactProximities.setValue(value);
380418
}
381419

420+
private void updateProphylaxisSectionVisibility() {
421+
422+
boolean imiVisible = Disease.INVASIVE_MENINGOCOCCAL_INFECTION == disease;
423+
424+
// Re-check @Diseases(IMI) against the current disease AND @HideForCountriesExcept("lu") against the deployment country.
425+
FieldVisibilityCheckers checkers =
426+
FieldVisibilityCheckers.withDisease(disease).andWithCountry(FacadeProvider.getConfigFacade().getCountryLocale());
427+
428+
for (String propertyId : new String[] {
429+
ContactDto.PROPHYLAXIS_PRESCRIBED,
430+
ContactDto.PRESCRIBED_DRUG,
431+
ContactDto.PRESCRIBED_DRUG_TEXT }) {
432+
if (checkers.isVisible(ContactDto.class, propertyId)) {
433+
// Re-enable fields that were hidden and disallowed at init (e.g. directory flow, disease = null).
434+
addToVisibleAllowedFields(getField(propertyId));
435+
}
436+
}
437+
438+
if (imiVisible) {
439+
// Re-filter the drug options for the selected disease; the field factory populated them at construction time
440+
// (disease may have been null then, e.g. directory flow), so the list would otherwise show non-IMI drugs.
441+
FieldHelper.updateEnumData(
442+
(ComboBox) getField(ContactDto.PRESCRIBED_DRUG),
443+
Diseases.DiseasesConfiguration.getVisibleValues(Drug.class, disease));
444+
}
445+
446+
// Only the checkbox is toggled directly; the two dependent fields are driven by the setVisibleWhen rules.
447+
setVisible(imiVisible, ContactDto.PROPHYLAXIS_PRESCRIBED);
448+
if (!imiVisible) {
449+
getField(ContactDto.PROPHYLAXIS_PRESCRIBED).clear();
450+
getField(ContactDto.PRESCRIBED_DRUG).clear();
451+
getField(ContactDto.PRESCRIBED_DRUG_TEXT).clear();
452+
setVisible(false, ContactDto.PRESCRIBED_DRUG, ContactDto.PRESCRIBED_DRUG_TEXT);
453+
}
454+
455+
prophylaxisLabel.setVisible(imiVisible && checkers.isVisible(ContactDto.class, ContactDto.PROPHYLAXIS_PRESCRIBED));
456+
}
457+
382458
private void hideAndFillJurisdictionFields() {
383459

384460
region.setVisible(false);

0 commit comments

Comments
 (0)