diff --git a/app/src/main/java/org/dhis2/usescases/main/program/ProgramFragment.kt b/app/src/main/java/org/dhis2/usescases/main/program/ProgramFragment.kt index c842b2805f..66430c381f 100644 --- a/app/src/main/java/org/dhis2/usescases/main/program/ProgramFragment.kt +++ b/app/src/main/java/org/dhis2/usescases/main/program/ProgramFragment.kt @@ -90,7 +90,7 @@ class ProgramFragment : FragmentGlobalAbstract(), ProgramView { ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed, ) setContent { - val items by presenter.programs().observeAsState(emptyList()) + val items by presenter.programs.observeAsState() val state by presenter.downloadState().observeAsState() ProgramList( downLoadState = state, @@ -124,10 +124,6 @@ class ProgramFragment : FragmentGlobalAbstract(), ProgramView { //endregion - override fun swapProgramModelData(programs: List) { - binding.emptyView.visibility = if (programs.isEmpty()) View.VISIBLE else View.GONE - } - override fun showFilterProgress() { Bindings.setViewVisibility( binding.clearFilter, @@ -157,7 +153,7 @@ class ProgramFragment : FragmentGlobalAbstract(), ProgramView { val stepCondition = SparseBooleanArray() stepCondition.put( 7, - presenter.programs().value?.size ?: 0 > 0, + (presenter.programs.value?.size ?: 0) > 0, ) HelpManager.getInstance().show( abstractActivity, diff --git a/app/src/main/java/org/dhis2/usescases/main/program/ProgramPresenter.kt b/app/src/main/java/org/dhis2/usescases/main/program/ProgramPresenter.kt index 712f6eb906..c9c0eda051 100644 --- a/app/src/main/java/org/dhis2/usescases/main/program/ProgramPresenter.kt +++ b/app/src/main/java/org/dhis2/usescases/main/program/ProgramPresenter.kt @@ -1,5 +1,6 @@ package org.dhis2.usescases.main.program +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import io.reactivex.disposables.CompositeDisposable import io.reactivex.processors.PublishProcessor @@ -23,7 +24,8 @@ class ProgramPresenter internal constructor( private val syncStatusController: SyncStatusController, ) { - private val programs = MutableLiveData>(emptyList()) + private val _programs = MutableLiveData>() + val programs: LiveData> = _programs private val refreshData = PublishProcessor.create() var disposable: CompositeDisposable = CompositeDisposable() @@ -48,8 +50,7 @@ class ProgramPresenter internal constructor( .observeOn(schedulerProvider.ui()) .subscribe( { programs -> - this.programs.postValue(programs) - view.swapProgramModelData(programs) + _programs.postValue(programs) }, { throwable -> Timber.d(throwable) }, { Timber.tag("INIT DATA").d("LOADING ENDED") }, @@ -119,8 +120,6 @@ class ProgramPresenter internal constructor( filterManager.addOrgUnits(selectedOrgUnits) } - fun programs() = programs - fun downloadState() = syncStatusController.observeDownloadProcess() fun setIsDownloading() { diff --git a/app/src/main/java/org/dhis2/usescases/main/program/ProgramUi.kt b/app/src/main/java/org/dhis2/usescases/main/program/ProgramUi.kt index c932818531..8fa3b7525e 100644 --- a/app/src/main/java/org/dhis2/usescases/main/program/ProgramUi.kt +++ b/app/src/main/java/org/dhis2/usescases/main/program/ProgramUi.kt @@ -37,6 +37,8 @@ import androidx.compose.material.IconButton import androidx.compose.material.LocalTextStyle import androidx.compose.material.Text import androidx.compose.material.TextButton +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.ErrorOutline import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue @@ -71,10 +73,14 @@ import org.dhis2.data.service.SyncStatusData import org.dhis2.ui.MetadataIcon import org.dhis2.ui.MetadataIconData import org.hisp.dhis.android.core.common.State +import org.hisp.dhis.mobile.ui.designsystem.component.InfoBar +import org.hisp.dhis.mobile.ui.designsystem.component.InfoBarData +import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing +import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor @Composable fun ProgramList( - programs: List, + programs: List?, onItemClick: (programViewModel: ProgramViewModel) -> Unit, onGranularSyncClick: (programViewModel: ProgramViewModel) -> Unit, downLoadState: SyncStatusData?, @@ -96,44 +102,51 @@ fun ProgramList( DownloadMedia() } - when (conf.orientation) { - Configuration.ORIENTATION_LANDSCAPE -> - LazyVerticalGrid( - columns = GridCells.Fixed(3), - contentPadding = PaddingValues(bottom = 56.dp), - ) { - items(items = programs) { program -> - ProgramItem( - programViewModel = program, - onItemClick = onItemClick, - onGranularSyncClick = onGranularSyncClick, - ) - Divider( - color = colorResource(id = R.color.divider_bg), - thickness = 1.dp, - startIndent = 72.dp, - ) + programs?.let { + if (programs.isEmpty()) { + NoAccessMessage() + } + + when (conf.orientation) { + Configuration.ORIENTATION_LANDSCAPE -> + LazyVerticalGrid( + columns = GridCells.Fixed(3), + contentPadding = PaddingValues(bottom = 56.dp), + ) { + items(items = programs) { program -> + ProgramItem( + programViewModel = program, + onItemClick = onItemClick, + onGranularSyncClick = onGranularSyncClick, + ) + Divider( + color = colorResource(id = R.color.divider_bg), + thickness = 1.dp, + startIndent = 72.dp, + ) + } } - } - else -> - LazyColumn( - modifier = Modifier.testTag(HOME_ITEMS), - contentPadding = PaddingValues(bottom = 56.dp), - ) { - itemsIndexed(items = programs) { index, program -> - ProgramItem( - modifier = Modifier.semantics { testTag = HOME_ITEM.format(index) }, - programViewModel = program, - onItemClick = onItemClick, - onGranularSyncClick = onGranularSyncClick, - ) - Divider( - color = colorResource(id = R.color.divider_bg), - thickness = 1.dp, - startIndent = 72.dp, - ) + + else -> + LazyColumn( + modifier = Modifier.testTag(HOME_ITEMS), + contentPadding = PaddingValues(bottom = 56.dp), + ) { + itemsIndexed(items = programs) { index, program -> + ProgramItem( + modifier = Modifier.semantics { testTag = HOME_ITEM.format(index) }, + programViewModel = program, + onItemClick = onItemClick, + onGranularSyncClick = onGranularSyncClick, + ) + Divider( + color = colorResource(id = R.color.divider_bg), + thickness = 1.dp, + startIndent = 72.dp, + ) + } } - } + } } } } @@ -391,6 +404,26 @@ fun DownloadMedia() { } } +@Composable +@Preview +fun NoAccessMessage() { + InfoBar( + modifier = Modifier.padding(Spacing.Spacing16), + infoBarData = InfoBarData( + text = stringResource(id = R.string.no_data_access), + icon = { + Icon( + imageVector = Icons.Outlined.ErrorOutline, + contentDescription = "error", + tint = SurfaceColor.Warning, + ) + }, + color = SurfaceColor.Warning, + backgroundColor = SurfaceColor.WarningContainer, + ), + ) +} + @Preview @Composable fun ProgramTest() { diff --git a/app/src/main/java/org/dhis2/usescases/main/program/ProgramView.kt b/app/src/main/java/org/dhis2/usescases/main/program/ProgramView.kt index 4965a7a879..c2adb0a32d 100644 --- a/app/src/main/java/org/dhis2/usescases/main/program/ProgramView.kt +++ b/app/src/main/java/org/dhis2/usescases/main/program/ProgramView.kt @@ -5,8 +5,6 @@ import org.dhis2.usescases.general.AbstractActivityContracts interface ProgramView : AbstractActivityContracts.View { - fun swapProgramModelData(programs: List) - fun showFilterProgress() fun openOrgUnitTreeSelector() diff --git a/app/src/main/res/layout/fragment_program.xml b/app/src/main/res/layout/fragment_program.xml index 233b1eafb5..5dd9df8cca 100644 --- a/app/src/main/res/layout/fragment_program.xml +++ b/app/src/main/res/layout/fragment_program.xml @@ -78,16 +78,6 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/filter" /> - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 765818b11e..cfdcef1195 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -973,4 +973,5 @@ Mark for follow-up Remove Coordinates + You don’t have access to data.\nContact your administrator. diff --git a/app/src/test/java/org/dhis2/usescases/main/program/ProgramPresenterTest.kt b/app/src/test/java/org/dhis2/usescases/main/program/ProgramPresenterTest.kt index a4ea5e95fa..b4e30f6fb8 100644 --- a/app/src/test/java/org/dhis2/usescases/main/program/ProgramPresenterTest.kt +++ b/app/src/test/java/org/dhis2/usescases/main/program/ProgramPresenterTest.kt @@ -64,7 +64,6 @@ class ProgramPresenterTest { presenter.init() schedulers.io().advanceTimeBy(1, TimeUnit.SECONDS) verify(view).showFilterProgress() - verify(view).swapProgramModelData(programs) verify(view).openOrgUnitTreeSelector() }