Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
386aca5
Simprints RAMP ACF-1 unsaved program stage missing chart value fixed
alex-vt Jun 9, 2026
6346789
Simprints RAMP ACF-1,39,40,41 stale deleted entries set to not show i…
alex-vt Jun 9, 2026
7de56f8
Simprints RAMP ACF-1 larger text in charts
alex-vt Jun 9, 2026
a8f2979
Simprints RAMP ACF-39,40,41 History table tab replaces the upstream N…
alex-vt Jun 9, 2026
a5a6dea
Simprints RAMP ACF-39,40,41 Details tab added to the landscape tab ro…
alex-vt Jun 9, 2026
ae532a4
Simprints RAMP infra: RAMPcapture Version info in About
alex-vt Jun 9, 2026
f4a6262
Simprints RAMP v1-adjustments README updates
alex-vt Jun 9, 2026
a9a479f
Simprints RAMP ACF-39,40,41 Table tab replaces Notes tab only if the …
alex-vt Jun 9, 2026
5f213b7
Simprints RAMP ACF-1 optimization: avoiding reading from event reposi…
alex-vt Jun 9, 2026
2f44ff4
Simprints RAMP ACF-39,40,41 table row order following section order
alex-vt Jun 15, 2026
0e20aca
Simprints RAMP ACF-39,40,41 tables renamed from History to Chart
alex-vt Jun 15, 2026
19963a4
Simprints RAMP ACF-1 graphs have decimal places limited in datastore …
alex-vt Jun 15, 2026
02d4766
Simprints RAMP: search disabled in some programs (driven by datastore…
alex-vt Jun 17, 2026
62b6392
Simprints RAMP: README references updated
alex-vt Jun 17, 2026
e28b4cc
Simprints RAMP: ACF-39,40,41 table (Chart) tabs are now the only ones…
alex-vt Jun 23, 2026
7bfa76e
Simprints RAMP: Refer and Schedule "+" menu options removable from pr…
alex-vt Jun 24, 2026
c6145f1
Simprints RAMP: Consistent resilience against accidental whitespaces …
alex-vt Jul 1, 2026
0a3f8f4
Simprints RAMP: RampDatastoreRepository injection
alex-vt Jul 1, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ jobs:
- name: Build signed release APK
run: ./gradlew app:assembleDhis2Release
env:
RAMP_CAPTURE_VERSION: ${{ steps.release-info.outputs.forkNumber }}
SIGNING_KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
SIGNING_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
SIGNING_STORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
Expand Down
52 changes: 37 additions & 15 deletions README.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ android {
multiDexEnabled = true

val bitriseSentryDSN = System.getenv("SENTRY_DSN") ?: ""
val rampCaptureVersion = System.getenv("RAMP_CAPTURE_VERSION") ?: "local build"

buildConfigField("String", "SDK_VERSION", "\"" + libs.versions.dhis2sdk.get() + "\"")
buildConfigField("String", "RAMP_CAPTURE_VERSION", "\"$rampCaptureVersion\"")
buildConfigField("String", "MATOMO_URL", "\"https://usage.analytics.dhis2.org/matomo.php\"")
buildConfigField("long", "VERSION_CODE", "${defaultConfig.versionCode}")
buildConfigField("String", "VERSION_NAME", "\"${defaultConfig.versionName}\"")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ fun aboutRobot(aboutBody: AboutRobot.() -> Unit) {

class AboutRobot : BaseRobot() {

fun checkVersionNames(appName: String, sdkName: String) {
val appNameText = "App Version: $appName"
onView(withId(R.id.aboutApp)).check(matches(withText(appNameText)))
fun checkVersionNames(rampCaptureName: String, appName: String, sdkName: String) {
onView(withId(R.id.rampCaptureVersion)).check(matches(withText(rampCaptureName)))
onView(withId(R.id.aboutApp)).check(matches(withText(appName)))
onView(withId(R.id.appSDK)).check(matches(withText(sdkName)))
}
}
15 changes: 11 additions & 4 deletions app/src/androidTest/java/org/dhis2/usescases/about/AboutTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.dhis2.usescases.about
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.ActivityTestRule
import org.dhis2.bindings.buildInfo
import org.dhis2.bindings.rampCaptureBuildInfo
import org.dhis2.BuildConfig
import org.dhis2.R
import org.dhis2.usescases.BaseTest
Expand All @@ -21,6 +22,7 @@ class AboutTest : BaseTest() {
@Test
fun shouldCheckVersionsWhenOpenAboutScreen() {
startActivity()
val rampCaptureVersion = getRampCaptureVersionName()
val appVersion = getAppVersionName()
val sdkVersion = getSDKVersionName()

Expand All @@ -30,17 +32,22 @@ class AboutTest : BaseTest() {
}

aboutRobot {
checkVersionNames(appVersion, sdkVersion)
checkVersionNames(rampCaptureVersion, appVersion, sdkVersion)
}
}

private fun startActivity() {
rule.launchActivity(null)
}

private fun getAppVersionName(): String {
return context.buildInfo()
}
private fun getRampCaptureVersionName() =
String.format(
context.getString(R.string.ramp_capture_version),
context.rampCaptureBuildInfo(),
)

private fun getAppVersionName() =
String.format(context.getString(R.string.about_app), context.buildInfo())

private fun getSDKVersionName() =
String.format(context.getString(R.string.about_sdk), BuildConfig.SDK_VERSION)
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/org/dhis2/bindings/ContextExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ fun Context.buildInfo(): String =
"v${BuildConfig.VERSION_NAME} : ${BuildConfig.GIT_SHA} "
}

fun Context.rampCaptureBuildInfo(): String =
if (BuildConfig.BUILD_TYPE == "release") {
BuildConfig.RAMP_CAPTURE_VERSION
} else {
"${BuildConfig.RAMP_CAPTURE_VERSION} : ${BuildConfig.GIT_SHA} "
}

fun Fragment.checkSMSPermission(
requestPermission: Boolean,
request: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,15 @@ class EventHistoryTableRepository(
rows = followUpRows,
)
} else {
val rowsByDataElementUid = followUpRows.associateBy { row -> row.dataElementUid }

sections.mapNotNull { section ->
val sectionDataElementUids =
val rows =
section
.dataElements()
.orEmpty()
.mapNotNull { dataElement -> dataElement.uid() }
.toSet()
val rows = followUpRows.filter { row -> row.dataElementUid in sectionDataElementUids }
.mapNotNull { dataElement -> dataElement.uid()?.let(rowsByDataElementUid::get) }
.distinctBy { row -> row.dataElementUid }

rows
.takeIf { it.isNotEmpty() }
Expand Down Expand Up @@ -296,6 +297,8 @@ class EventHistoryTableRepository(
.eq(tableContext.enrollmentUid)
.byProgramStageUid()
.eq(followUpVisitProgramStageUid)
.byDeleted()
.isFalse
.blockingGet()
}
val events =
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/org/dhis2/usescases/about/AboutFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.dhis2.BuildConfig
import org.dhis2.R
import org.dhis2.bindings.app
import org.dhis2.bindings.buildInfo
import org.dhis2.bindings.rampCaptureBuildInfo
import org.dhis2.databinding.FragmentAboutBinding
import org.dhis2.usescases.general.FragmentGlobalAbstract
import org.hisp.dhis.android.core.user.User
Expand Down Expand Up @@ -41,6 +42,8 @@ class AboutFragment :
aboutGit.movementMethod = LinkMovementMethod.getInstance()
aboutDev.movementMethod = LinkMovementMethod.getInstance()
aboutContact.movementMethod = LinkMovementMethod.getInstance()
rampCaptureVersion.text =
getString(R.string.ramp_capture_version).format(context?.rampCaptureBuildInfo())
aboutApp.text = getString(R.string.about_app).format(context?.buildInfo())
appSDK.text = getString(R.string.about_sdk).format(BuildConfig.SDK_VERSION)
privacyPolicy.setOnClickListener { navigateToPrivacyPolicy() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ class EventCaptureActivity :
pageConfigurator!!.displayAnalytics(),
pageConfigurator!!.displayTableView(),
pageConfigurator!!.displayRelationships(),
pageConfigurator!!.displayNotes(),
intent.getBooleanExtra(OPEN_ERROR_LOCATION, false),
eventMode,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.dhis2.commons.network.NetworkUtils
import org.dhis2.commons.prefs.PreferenceProvider
import org.dhis2.commons.resources.ResourceManager
import org.dhis2.commons.schedulers.SchedulerProvider
import org.dhis2.commons.simprints.ramp.repository.RampDatastoreRepository
import org.dhis2.data.dhislogic.DhisEnrollmentUtils
import org.dhis2.data.forms.dataentry.SearchTEIRepository
import org.dhis2.data.forms.dataentry.SearchTEIRepositoryImpl
Expand Down Expand Up @@ -62,7 +63,12 @@ class EventCaptureModule(

@Provides
@PerActivity
fun provideRepository(d2: D2?): EventCaptureRepository = EventCaptureRepositoryImpl(eventUid, d2)
fun provideRepository(d2: D2): EventCaptureRepository =
EventCaptureRepositoryImpl(
eventUid,
d2,
RampDatastoreRepository(d2),
)

@Provides
@PerActivity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class EventCapturePagerAdapter(
displayAnalyticScreen: Boolean,
displaySimprintsRampHistoryTableScreen: Boolean,
displayRelationshipScreen: Boolean,
displayNotes: Boolean,
private val shouldOpenErrorSection: Boolean,
private val eventMode: EventMode,
) : FragmentStateAdapter(fragmentActivity) {
Expand Down Expand Up @@ -59,8 +60,11 @@ class EventCapturePagerAdapter(
portraitPages.add(EventPageType.RELATIONSHIPS)
landscapePages.add(EventPageType.RELATIONSHIPS)
}
portraitPages.add(EventPageType.NOTES)
landscapePages.add(EventPageType.NOTES)

if (displayNotes) {
portraitPages.add(EventPageType.NOTES)
landscapePages.add(EventPageType.NOTES)
}

if (displaySimprintsRampHistoryTableScreen) {
portraitPages.add(EventPageType.SIMPRINTS_RAMP_HISTORY_TABLE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class EventCapturePresenterImpl(

private fun loadBottomBarItems() {
val navItems = mutableListOf<NavigationBarItem<NavigationPage>>()
val displayTableView = pageConfigurator.displayTableView()

if (pageConfigurator.displayDataEntry() || forceDisplayDataEntryNavigationItemForSimprintsRampTable) {
navItems.add(
Expand Down Expand Up @@ -152,20 +153,27 @@ class EventCapturePresenterImpl(
)
}

if (pageConfigurator.displayTableView()) {
if (displayTableView) {
navItems.add(
NavigationBarItem(
id = NavigationPage.TABLE_VIEW,
icon = Icons.Outlined.TableChart,
selectedIcon = Icons.Filled.TableChart,
label = resourceManager.getString(R.string.navigation_simprints_ramp_history),
label = resourceManager.getString(R.string.navigation_simprints_ramp_history_chart),
),
)
}

val visibleItems = navItems.takeIf { it.size > 1 || displayTableView }.orEmpty()
val selectedItem =
navigationBarUIState.value.selectedItem
?.takeIf { item -> visibleItems.any { it.id == item } }
?: visibleItems.firstOrNull()?.id

navigationBarUIState.value =
navigationBarUIState.value.copy(
items = navItems.takeIf { it.size > 1 }.orEmpty(),
items = visibleItems,
selectedItem = selectedItem,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.gson.Gson;

import org.dhis2.commons.bindings.SdkExtensionsKt;
import org.dhis2.commons.simprints.ramp.model.ProgramStageHistoryTableConfig;
import org.dhis2.commons.simprints.ramp.repository.RampDatastoreRepository;
Expand Down Expand Up @@ -38,10 +36,10 @@ public class EventCaptureRepositoryImpl implements EventCaptureContract.EventCap
private final D2 d2;
private final RampDatastoreRepository rampDatastoreRepository;

public EventCaptureRepositoryImpl(String eventUid, D2 d2) {
public EventCaptureRepositoryImpl(String eventUid, D2 d2, RampDatastoreRepository rampDatastoreRepository) {
this.eventUid = eventUid;
this.d2 = d2;
this.rampDatastoreRepository = new RampDatastoreRepository(d2, new Gson());
this.rampDatastoreRepository = rampDatastoreRepository;
}

private Event getCurrentEvent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ class EventPageConfigurator(

override fun displayDataEntry(): Boolean = isPortrait

override fun displayAnalytics(): Boolean = eventCaptureRepository.hasAnalytics()
override fun displayAnalytics(): Boolean = eventCaptureRepository.hasAnalytics() && !displayTableView()

override fun displayRelationships(): Boolean = eventCaptureRepository.hasRelationships()

override fun displayNotes(): Boolean = true
override fun displayNotes(): Boolean = !displayTableView()

override fun displayTableView(): Boolean = eventCaptureRepository.hasSimprintsRampProgramStageHistoryTable()
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ fun ComposeView?.setLandscapeOpenSearchButton(
DHIS2Theme {
val screenState by searchTEIViewModel.screenState.observeAsState()
val teTypeName by searchTEIViewModel.teTypeName.observeAsState()
val isSearchEnabled by searchTEIViewModel.isSearchEnabled.observeAsState(true)

val visible =
screenState?.let {
(it is SearchList) && it.searchFilters.isOpened
} ?: false
val isLandscape =
LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE
AnimatedVisibility(visible = isLandscape && visible && !teTypeName.isNullOrBlank()) {
AnimatedVisibility(visible = isLandscape && visible && isSearchEnabled && !teTypeName.isNullOrBlank()) {
WrappedSearchButton(onClick = onClick, teTypeName = teTypeName!!)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ public interface SearchRepository {

boolean canCreateInProgramWithoutSearch();

boolean isSearchEnabled();

void setCurrentTheme(@org.jetbrains.annotations.Nullable ProgramSpinnerModel selectedProgram);

List<String> trackedEntityTypeFields();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.dhis2.commons.resources.DhisPeriodUtils;
import org.dhis2.commons.resources.MetadataIconProvider;
import org.dhis2.commons.resources.ResourceManager;
import org.dhis2.commons.simprints.ramp.repository.RampDatastoreRepository;
import org.dhis2.data.dhislogic.DhisEnrollmentUtils;
import org.dhis2.data.forms.dataentry.SearchTEIRepository;
import org.dhis2.data.forms.dataentry.ValueStore;
Expand Down Expand Up @@ -124,6 +125,7 @@ public class SearchRepositoryImpl implements SearchRepository {

private final MetadataIconProvider metadataIconProvider;
private final ProfilePictureProvider profilePictureProvider;
private final RampDatastoreRepository rampDatastoreRepository;
private CustomIntentRepository customIntentRepository;

SearchRepositoryImpl(String teiType,
Expand All @@ -141,7 +143,8 @@ public class SearchRepositoryImpl implements SearchRepository {
MetadataIconProvider metadataIconProvider,
ProfilePictureProvider profilePictureProvider,
DateUtils dateUtils,
CustomIntentRepository customIntentRepository
CustomIntentRepository customIntentRepository,
RampDatastoreRepository rampDatastoreRepository
) {
this.teiType = teiType;
this.d2 = d2;
Expand All @@ -165,6 +168,7 @@ public class SearchRepositoryImpl implements SearchRepository {
this.metadataIconProvider = metadataIconProvider;
this.profilePictureProvider = profilePictureProvider;
this.customIntentRepository = customIntentRepository;
this.rampDatastoreRepository = rampDatastoreRepository;
}


Expand Down Expand Up @@ -1012,6 +1016,11 @@ public boolean canCreateInProgramWithoutSearch() {
}
}

@Override
public boolean isSearchEnabled() {
return rampDatastoreRepository.isSearchEnabled(currentProgram);
}

private boolean displayOrgUnit() {
return d2.organisationUnitModule().organisationUnits()
.byProgramUids(Collections.singletonList(currentProgram))
Expand All @@ -1022,4 +1031,3 @@ private boolean displayOrgUnit() {

}


Loading