Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ updates:
commit-message:
prefix: "deps"
ignore:
- dependency-name: "*"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
Comment on lines +18 to +19
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wildcard dependency ignore pattern will ignore ALL major and minor version updates for all dependencies. This is an overly broad configuration that could prevent important security updates and bug fixes from being detected. Consider being more selective about which dependencies should have version updates ignored, or use more specific patterns that target only problematic dependencies.

Suggested change
- dependency-name: "*"
update-types: ["version-update:semver-major", "version-update:semver-minor"]

Copilot uses AI. Check for mistakes.
- dependency-name: "com.squareup.okhttp3:*"
- dependency-name: "org.hisp.dhis.mobile:designsystem"
- dependency-name: "org.hisp.dhis:android-core"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build-release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
run: ./gradlew --dependency-verification lenient app:assembleDhis2Release app:assembleDhis2PlayServicesRelease
env:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SIGNING_KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
SIGNING_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
SIGNING_STORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
Expand All @@ -63,6 +64,7 @@ jobs:
- name: Build Training APK
env:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
TRAINING_KEY_ALIAS: ${{ secrets.TRAINING_KEY_ALIAS }}
TRAINING_KEY_PASSWORD: ${{ secrets.TRAINING_KEY_PASSWORD }}
TRAINING_STORE_PASSWORD: ${{ secrets.TRAINING_STORE_PASSWORD }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/deploy-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ jobs:
run: ./gradlew --dependency-verification lenient app:assembleDhis2Release app:assembleDhis2PlayServicesRelease
env:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SIGNING_KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
SIGNING_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
SIGNING_STORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
Expand All @@ -67,6 +68,7 @@ jobs:
- name: Build Training APK
env:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
TRAINING_KEY_ALIAS: ${{ secrets.TRAINING_KEY_ALIAS }}
TRAINING_KEY_PASSWORD: ${{ secrets.TRAINING_KEY_PASSWORD }}
TRAINING_STORE_PASSWORD: ${{ secrets.TRAINING_STORE_PASSWORD }}
Expand Down
76 changes: 68 additions & 8 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,75 @@
# Release notes - Android App for DHIS2 - 3.3.0.1
# Release notes - Android App for DHIS2 - 3.3.1

This patch release includes updated translations and a hotfix.
### Bug

## Bugs fixed
[ANDROAPP-6870](https://dhis2.atlassian.net/browse/ANDROAPP-6870) Let the rule-engine apply the logic for useCodeForOptionSet in RuleVariable

* [ANDROSDK-2219](https://dhis2.atlassian.net/browse/ANDROSDK-2219) Tracker sync fail due to null properties in Note
[ANDROAPP-6975](https://dhis2.atlassian.net/browse/ANDROAPP-6975) Crash when rotating the device with the save dialog open

* [ANDROSDK-2221](https://dhis2.atlassian.net/browse/ANDROSDK-2221) Data set with default cat combo can't be edited
[ANDROAPP-7211](https://dhis2.atlassian.net/browse/ANDROAPP-7211) NoSuchElementException: Collection contains no element matching the predicate.

* [ANDROSDK-2223](https://dhis2.atlassian.net/browse/ANDROSDK-2223) openingDate and closedDate from DataInputPeriod are nullable
[ANDROAPP-7235](https://dhis2.atlassian.net/browse/ANDROAPP-7235) Program rules not triggered when moving between fields manually

### Translations
[ANDROAPP-7260](https://dhis2.atlassian.net/browse/ANDROAPP-7260) Incorrect behavior when creating a new event in timeline view

This release also includes updated translations contributed by the community.
[ANDROAPP-7261](https://dhis2.atlassian.net/browse/ANDROAPP-7261) Keyboard blocks the last field when entering data \(screen doesn’t scroll\)

[ANDROAPP-7269](https://dhis2.atlassian.net/browse/ANDROAPP-7269) Crash on search

[ANDROAPP-7293](https://dhis2.atlassian.net/browse/ANDROAPP-7293) Bottom sheet landscape behavior

[ANDROAPP-7345](https://dhis2.atlassian.net/browse/ANDROAPP-7345) Changes to enrollment date not respected by program rules \(version 3.2.1.2\)

[ANDROAPP-7368](https://dhis2.atlassian.net/browse/ANDROAPP-7368) crash: when trying to update fields in Tracker

[ANDROAPP-7394](https://dhis2.atlassian.net/browse/ANDROAPP-7394) Login blocked after logout “The user is already logged in” error

[ANDROAPP-7400](https://dhis2.atlassian.net/browse/ANDROAPP-7400) Crash - changing org unit and dates

[ANDROAPP-7402](https://dhis2.atlassian.net/browse/ANDROAPP-7402) Bottom sheet org unit not displaying buttons

[ANDROAPP-7403](https://dhis2.atlassian.net/browse/ANDROAPP-7403) Home cards lose proper layout

[ANDROAPP-7411](https://dhis2.atlassian.net/browse/ANDROAPP-7411) Android sync by working lists: After updating predefined list views settings, changes aren't reflected in android app after syncing

[ANDROAPP-7415](https://dhis2.atlassian.net/browse/ANDROAPP-7415) Android: WORKING LIST incorrect result in app

[ANDROAPP-7419](https://dhis2.atlassian.net/browse/ANDROAPP-7419) Server selection title is missing

[ANDROAPP-7421](https://dhis2.atlassian.net/browse/ANDROAPP-7421) Data set table not opening after clicking next for default category combo

[ANDROAPP-7425](https://dhis2.atlassian.net/browse/ANDROAPP-7425) NullPointerException: ProgramFragment

[ANDROAPP-7428](https://dhis2.atlassian.net/browse/ANDROAPP-7428) LMIS program is using completed enrollment

[ANDROAPP-7442](https://dhis2.atlassian.net/browse/ANDROAPP-7442) Program rules not triggering for completed enrollments

### Task

[ANDROAPP-7286](https://dhis2.atlassian.net/browse/ANDROAPP-7286) Replace deprecated categoryComboUid usages with categoryCombo in Program and DataElement

[ANDROAPP-7288](https://dhis2.atlassian.net/browse/ANDROAPP-7288) Implement UseCase interface

[ANDROAPP-7318](https://dhis2.atlassian.net/browse/ANDROAPP-7318) Create AGENTS.md file

[ANDROAPP-7349](https://dhis2.atlassian.net/browse/ANDROAPP-7349) Sonarcloud - Use full commit SHA hash for this dependency.

[ANDROAPP-7373](https://dhis2.atlassian.net/browse/ANDROAPP-7373) LogoutUser use case improvements

[ANDROAPP-7384](https://dhis2.atlassian.net/browse/ANDROAPP-7384) Update transifex tracker configuration

[ANDROAPP-7386](https://dhis2.atlassian.net/browse/ANDROAPP-7386) QA: Remove duplicated UI modules

[ANDROAPP-7388](https://dhis2.atlassian.net/browse/ANDROAPP-7388) Create sync module

[ANDROAPP-7395](https://dhis2.atlassian.net/browse/ANDROAPP-7395) Review settings repository data loading for log out request

[ANDROAPP-7396](https://dhis2.atlassian.net/browse/ANDROAPP-7396) Remove and update usage to design systems' deprecated methods

[ANDROAPP-7424](https://dhis2.atlassian.net/browse/ANDROAPP-7424) Gradle warnings: Remove RX binding dependency and zxing dependency

[ANDROAPP-7426](https://dhis2.atlassian.net/browse/ANDROAPP-7426) Upload proguard mapping on Sentry

[ANDROAPP-7440](https://dhis2.atlassian.net/browse/ANDROAPP-7440) Update Expression parser to 1.2.2

[ANDROAPP-7441](https://dhis2.atlassian.net/browse/ANDROAPP-7441) Remove username from Sentry reports
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<string name="field_required">Si introduce un valor, tendrá que completar toda la fila para poder marcar como Completado el Data Set.</string>
<string name="ok">Correcto</string>
<string name="dataset_saved_completed">¡Guardado y completado!</string>
<string name="run_validation_rules">¿Quieree validar la calidad de los datos?</string>
<string name="run_validation_rules">¿Quiere validar la calidad de los datos?</string>
<string name="no">No</string>
<string name="yes">Sí</string>
<string name="error">Error</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<string name="ok">Aceptar</string>
<string name="dataset_saved_completed">¡Guardado y completado!</string>
<string name="error_on_complete_dataset">Ha ocurrido un error al completar el conjunto de datos</string>
<string name="run_validation_rules">¿Quieree validar la calidad de los datos?</string>
<string name="run_validation_rules">¿Quiere validar la calidad de los datos?</string>
<string name="no">No</string>
<string name="yes">Sí</string>
<string name="error">Error</string>
Expand Down
36 changes: 36 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ plugins {
id("kotlin-parcelize")
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlin.compose.compiler)
alias(libs.plugins.sentry)
}
apply(from = "${project.rootDir}/jacoco/jacoco.gradle.kts")

Expand Down Expand Up @@ -316,3 +317,38 @@ dependencies {
androidTestImplementation(libs.test.compose.ui.test)
androidTestImplementation(libs.test.hamcrest)
}

sentry {
org.set("dhis2")
projectName.set("dhis2-android-capture")

val sentryAuthToken = System.getenv("SENTRY_AUTH_TOKEN")
if (!sentryAuthToken.isNullOrBlank()) {
authToken.set(sentryAuthToken)

// Enable ProGuard/R8 mapping upload for deobfuscation, maps are available in the build folder
includeProguardMapping.set(true)
// Upload the mapping on every release build
autoUploadProguardMapping.set(true)
} else {
// When no auth token is available (e.g., local development), disable uploads
includeProguardMapping.set(false)
autoUploadProguardMapping.set(false)
}

// Disable native symbols upload (not needed for this project)
uploadNativeSymbols.set(false)
includeNativeSources.set(false)

// Enable auto-installation of Sentry components (sentry-android SDK and okhttp, timber, fragment and compose integrations).
autoInstallation {
enabled.set(false)
sentryVersion.set(libs.versions.sentry)
}

// Disabled to avoid uploading source code to Sentry; rely on ProGuard/R8 mappings instead.
includeSourceContext.set(false)

// Telemetry
telemetry.set(false)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import java.time.LocalDate
import java.time.format.DateTimeFormatter


Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @OptIn(ExperimentalTestApi::class) annotation has been added to the class level. The waitUntilExactlyOneExists function is from the ExperimentalTestApi. While this is a valid approach to resolve flaky tests, be aware that experimental APIs may change in future versions of the Compose testing library. Consider adding a comment explaining why this experimental API is needed (to fix flaky test behavior when creating multiple dataset instances).

Suggested change
// Opt in to ExperimentalTestApi to use waitUntilExactlyOneExists for stabilizing
// flaky Compose tests when creating multiple dataset instances.

Copilot uses AI. Check for mistakes.
@OptIn(ExperimentalTestApi::class)
@RunWith(AndroidJUnit4::class)
class DataSetTest : BaseTest() {

Expand Down Expand Up @@ -324,6 +325,11 @@ class DataSetTest : BaseTest() {
orgUnit = orgUnit,
catCombo = catCombo
)
// Wait for table to be ready after creating the second dataset instance
composeTestRule.waitUntilExactlyOneExists(
hasTestTag("TABLE_SCROLLABLE_COLUMN"),
timeoutMillis = 10000
)
tableIsVisible()
enterDataStep(
tableId = tableId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class SplashPresenter internal constructor(
trackUserInfo(
serverUrl = systemInfo?.contextPath() ?: "",
serverVersion = systemInfo?.version() ?: "",
userName = userManager.userName().blockingGet(),
)
}
view.goToNextScreen(
Expand Down Expand Up @@ -87,10 +86,8 @@ class SplashPresenter internal constructor(
private fun trackUserInfo(
serverUrl: String,
serverVersion: String,
userName: String,
) {
crashReportController.trackServer(serverUrl, serverVersion)
crashReportController.trackUser(userName, serverUrl)
}

fun getAccounts(): Int =
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-cs/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -688,9 +688,9 @@
<string name="dataset_overview">Detaily</string>
<string name="dataset_comments">Komentáře</string>
<string name="saved">Uloženo!</string>
<string name="run_validation_rules">Chcete zkontrolovat kvalitu dat\?</string>
<string name="run_validation_rules">Chcete zkontrolovat kvalitu dat?</string>
<string name="validation_success_title">Všechno vypadá dobře!</string>
<string name="mark_dataset_complete">Chcete také vyplnit soubor dat\?</string>
<string name="mark_dataset_complete">Chcete také vyplnit soubor dat?</string>
<string name="dataset_completed">Označit jak dokončené</string>
<string name="name">Název</string>
<string name="formula">Vzorec</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-es-rES/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -649,9 +649,9 @@
<string name="dataset_overview">Detalles</string>
<string name="dataset_comments">Comentarios</string>
<string name="saved">¡Guardado!</string>
<string name="run_validation_rules">¿Quieree validar la calidad de los datos\?</string>
<string name="run_validation_rules">¿Quiere validar la calidad de los datos?</string>
<string name="validation_success_title">¡Parece que todo está bien!</string>
<string name="mark_dataset_complete">¿Quiere completar también el set de datos\?</string>
<string name="mark_dataset_complete">¿Quiere completar también el set de datos?</string>
<string name="dataset_completed">Marcar como completado</string>
<string name="name">Nombre</string>
<string name="formula">Fórmula</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -681,9 +681,9 @@
<string name="dataset_overview">Detalles</string>
<string name="dataset_comments">Comentarios</string>
<string name="saved">¡Guardado!</string>
<string name="run_validation_rules">¿Quieree validar la calidad de los datos\?</string>
<string name="run_validation_rules">¿Quiere validar la calidad de los datos?</string>
<string name="validation_success_title">¡Parece que todo está bien!</string>
<string name="mark_dataset_complete">¿Quiere completar también el set de datos\?</string>
<string name="mark_dataset_complete">¿Quiere completar también el set de datos?</string>
<string name="dataset_completed">Marcar como completado</string>
<string name="name">Nombre</string>
<string name="formula">Fórmula</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -658,9 +658,9 @@
<string name="dataset_overview">Details</string>
<string name="dataset_comments">Commentaires</string>
<string name="saved">Enregistré!</string>
<string name="run_validation_rules">Voulez-vous vérifier la qualité des données\?</string>
<string name="run_validation_rules">Voulez-vous vérifier la qualité des données?</string>
<string name="validation_success_title">Tout a l\'air bien!</string>
<string name="mark_dataset_complete">Voulez-vous également compléter l\'ensemble de données\?</string>
<string name="mark_dataset_complete">Voulez-vous également compléter l\'ensemble de données?</string>
<string name="dataset_completed">Marquer comme terminé</string>
<string name="name">Nom</string>
<string name="formula">Formule</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-id/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,9 @@
<string name="dataset_overview">Rincian</string>
<string name="dataset_comments">Komentar</string>
<string name="saved">Tersimpan!</string>
<string name="run_validation_rules">Apakah Anda ingin memeriksa kualitas data\?</string>
<string name="run_validation_rules">Apakah Anda ingin memeriksa kualitas data?</string>
<string name="validation_success_title">Semuanya terlihat bagus!</string>
<string name="mark_dataset_complete">Apakah Anda juga ingin melengkapi data set\?</string>
<string name="mark_dataset_complete">Apakah Anda juga ingin melengkapi data set?</string>
<string name="dataset_completed">Tandai sebagai selesai</string>
<string name="name">Nama</string>
<string name="formula">Formula</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-lo/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,9 @@
<string name="dataset_overview">ລາຍລະອຽດ</string>
<string name="dataset_comments">ຄຳເຫັນ</string>
<string name="saved">ບັນທຶກແລ້ວ!</string>
<string name="run_validation_rules">ທ່ານຕ້ອງການກວດສອບຄຸນນະພາບຂໍ້ມູນນີ້ບໍ\?</string>
<string name="run_validation_rules">ທ່ານຕ້ອງການກວດສອບຄຸນນະພາບຂໍ້ມູນນີ້ບໍ?</string>
<string name="validation_success_title">ທຸກຢ່າງຮຽບຮ້ອຍດີ</string>
<string name="mark_dataset_complete">ທ່ານຕ້ອງການເຮັດຊຸດຂໍ້ມູນໃຫ້ຄົບຖ້ວນບໍ\?</string>
<string name="mark_dataset_complete">ທ່ານຕ້ອງການເຮັດຊຸດຂໍ້ມູນໃຫ້ຄົບຖ້ວນບໍ?</string>
<string name="dataset_completed">ເຮັດໃຫ້ສຳເລັດແລ້ວ</string>
<string name="name">ຊື່</string>
<string name="formula">Formula</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-nb/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,9 @@
<string name="dataset_overview">Detaljer</string>
<string name="dataset_comments">Kommentarer</string>
<string name="saved">Lagret!</string>
<string name="run_validation_rules">Vil du sjekke datakvaliteten\?</string>
<string name="run_validation_rules">Vil du sjekke datakvaliteten?</string>
<string name="validation_success_title">Alt ser bra ut</string>
<string name="mark_dataset_complete">Vil du også fullføre datasettet\?</string>
<string name="mark_dataset_complete">Vil du også fullføre datasettet?</string>
<string name="dataset_completed">Merk som fullført</string>
<string name="name">Navn</string>
<string name="formula">Formel</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-nl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,9 @@
<string name="dataset_overview">Details</string>
<string name="dataset_comments">Opmerkingen</string>
<string name="saved">Opgeslagen!</string>
<string name="run_validation_rules">Wilt u de datakwaliteit controleren\?</string>
<string name="run_validation_rules">Wilt u de datakwaliteit controleren?</string>
<string name="validation_success_title">Alles ziet er goed uit!</string>
<string name="mark_dataset_complete">Wil je ook de dataset compleet maken\?</string>
<string name="mark_dataset_complete">Wil je ook de dataset compleet maken?</string>
<string name="dataset_completed">Markeer als voltooid</string>
<string name="name">Naam</string>
<string name="formula">Formule</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-pt/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -678,9 +678,9 @@
<string name="dataset_overview">Detalhes</string>
<string name="dataset_comments">Comentarios</string>
<string name="saved">Gravado!</string>
<string name="run_validation_rules">Você quer verificar a qualidade dos dados\?</string>
<string name="run_validation_rules">Você quer verificar a qualidade dos dados?</string>
<string name="validation_success_title">Tudo parece bem!</string>
<string name="mark_dataset_complete">Você também deseja completar o conjunto de dados\?</string>
<string name="mark_dataset_complete">Você também deseja completar o conjunto de dados?</string>
<string name="dataset_completed">Marcar como completado</string>
<string name="name">Nome</string>
<string name="formula">Fórmula</string>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,9 @@
<string name="dataset_overview">Детали</string>
<string name="dataset_comments">Комментарии</string>
<string name="saved">Сохранено!</string>
<string name="run_validation_rules">Вы хотите проверить качество данных\?</string>
<string name="run_validation_rules">Вы хотите проверить качество данных?</string>
<string name="validation_success_title">Все выглядит хорошо!</string>
<string name="mark_dataset_complete">Вы также хотите завершить набор данных\?</string>
<string name="mark_dataset_complete">Вы также хотите завершить набор данных?</string>
<string name="dataset_completed">Отметить как завершенное</string>
<string name="name">Название</string>
<string name="formula">Формула</string>
Expand Down
Loading