From 9d81916465362d7277155833f536b45c5bfd789f Mon Sep 17 00:00:00 2001 From: Ferdy Rodriguez Date: Thu, 27 Jun 2024 13:59:27 +0200 Subject: [PATCH] fix: [ANDROAPP-6158] Shows messages when data set section is empty (#3703) --- .../dataSetSection/DataSetSectionFragment.kt | 1 + .../dataSetSection/DataValuePresenter.kt | 3 +- app/src/main/res/values/strings.xml | 1 + .../java/org/dhis2/composetable/TableRobot.kt | 37 ++++++++++++++ .../composetable/ui/DataSetTableUiTest.kt | 18 ++++++- .../dhis2/composetable/TableScreenState.kt | 6 +++ .../composetable/ui/DataSetTableScreen.kt | 49 +++++++++++++++++-- .../ui/managestock/ManageStockViewModel.kt | 2 + 8 files changed, 110 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataSetSectionFragment.kt b/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataSetSectionFragment.kt index 75d74aa135..84f22b818c 100644 --- a/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataSetSectionFragment.kt +++ b/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataSetSectionFragment.kt @@ -209,6 +209,7 @@ class DataSetSectionFragment : FragmentGlobalAbstract(), DataValueContract.View onCellClick = presenterFragment::onCellClick, onEdition = presenter::editingCellValue, onSaveValue = presenterFragment::onSaveValueChange, + emptyTablesText = getString(R.string.section_misconfigured), ) } } diff --git a/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataValuePresenter.kt b/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataValuePresenter.kt index 434b519908..36310c14dd 100644 --- a/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataValuePresenter.kt +++ b/app/src/main/java/org/dhis2/usescases/datasets/dataSetTable/dataSetSection/DataValuePresenter.kt @@ -15,6 +15,7 @@ import org.dhis2.commons.schedulers.SchedulerProvider import org.dhis2.commons.viewmodel.DispatcherProvider import org.dhis2.composetable.TableConfigurationState import org.dhis2.composetable.TableScreenState +import org.dhis2.composetable.TableState import org.dhis2.composetable.actions.Validator import org.dhis2.composetable.model.TableCell import org.dhis2.composetable.model.TableModel @@ -79,7 +80,7 @@ class DataValuePresenter( .subscribe( { screenState.update { currentScreenState -> - currentScreenState.copy(tables = it.tables) + currentScreenState.copy(tables = it.tables, state = TableState.SUCCESS) } }, { Timber.e(it) }, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c0bce83893..40fb2d39e9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -978,4 +978,5 @@ Show fields Hide fields Import successful + This section is misconfigured.\nContact your administrator. diff --git a/compose-table/src/androidTest/java/org/dhis2/composetable/TableRobot.kt b/compose-table/src/androidTest/java/org/dhis2/composetable/TableRobot.kt index 43e8955d4c..06424d9d2e 100644 --- a/compose-table/src/androidTest/java/org/dhis2/composetable/TableRobot.kt +++ b/compose-table/src/androidTest/java/org/dhis2/composetable/TableRobot.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.test.assertIsNotDisplayed import androidx.compose.ui.test.assertTextEquals import androidx.compose.ui.test.hasParent import androidx.compose.ui.test.hasTestTag +import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.performClick @@ -40,6 +41,7 @@ import org.dhis2.composetable.model.TextInputModel import org.dhis2.composetable.ui.DataSetTableScreen import org.dhis2.composetable.ui.DataTable import org.dhis2.composetable.ui.DrawableId +import org.dhis2.composetable.ui.EMPTY_TABLE_TEXT_TAG import org.dhis2.composetable.ui.INPUT_ERROR_MESSAGE_TEST_TAG import org.dhis2.composetable.ui.INPUT_HELPER_TEXT_TEST_TAG import org.dhis2.composetable.ui.INPUT_ICON_TEST_TAG @@ -176,6 +178,33 @@ class TableRobot( return fakeModel } + fun initEmptyTableAppScreen( + emptyTablesText: String, + ): List { + val fakeModel: List = emptyList() + composeTestRule.setContent { + val screenState = TableScreenState(fakeModel, state = TableState.SUCCESS) + + val model by remember { mutableStateOf(screenState) } + TableTheme( + tableColors = TableColors().copy(primary = MaterialTheme.colors.primary), + tableConfiguration = TableConfiguration(), + tableResizeActions = object : TableResizeActions {} + ) { + DataSetTableScreen( + tableScreenState = model, + onCellClick = { _, _, _ -> + null + }, + emptyTablesText = emptyTablesText, + onEdition = {}, + onSaveValue = {} + ) + } + } + return fakeModel + } + private fun updateValue(fakeModel: List, tableCell: TableCell): List { return fakeModel.map { tableModel -> val hasRowWithDataElement = tableModel.tableRows.find { @@ -456,4 +485,12 @@ class TableRobot( fun hideKeyboard() { keyboardHelper.hideKeyboard() } + + fun assertInfoBarIsVisible(emptyString: String) { + composeTestRule.onNode( + hasParent(hasTestTag(EMPTY_TABLE_TEXT_TAG)) + and + hasText(emptyString) + ).assertIsDisplayed() + } } \ No newline at end of file diff --git a/compose-table/src/androidTest/java/org/dhis2/composetable/ui/DataSetTableUiTest.kt b/compose-table/src/androidTest/java/org/dhis2/composetable/ui/DataSetTableUiTest.kt index 75b8fcd759..2685ac04bc 100644 --- a/compose-table/src/androidTest/java/org/dhis2/composetable/ui/DataSetTableUiTest.kt +++ b/compose-table/src/androidTest/java/org/dhis2/composetable/ui/DataSetTableUiTest.kt @@ -1,8 +1,13 @@ package org.dhis2.composetable.ui import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.hasParent +import androidx.compose.ui.test.hasTestTag +import androidx.compose.ui.test.hasText import androidx.compose.ui.test.junit4.createComposeRule import org.dhis2.composetable.model.FakeTableModels +import org.dhis2.composetable.tableRobot import org.junit.Rule import org.junit.Test @@ -20,4 +25,15 @@ class DataSetTableUiTest { ) } } -} \ No newline at end of file + + @Test + fun shouldRenderInfoBarIfTableListIsEmpty() { + tableRobot(composeTestRule) { + initEmptyTableAppScreen( + emptyTablesText = "Section is misconfigured" + ) + + assertInfoBarIsVisible("Section is misconfigured") + } + } +} diff --git a/compose-table/src/main/java/org/dhis2/composetable/TableScreenState.kt b/compose-table/src/main/java/org/dhis2/composetable/TableScreenState.kt index 3b40f2d161..a558287e25 100644 --- a/compose-table/src/main/java/org/dhis2/composetable/TableScreenState.kt +++ b/compose-table/src/main/java/org/dhis2/composetable/TableScreenState.kt @@ -6,6 +6,7 @@ import java.util.UUID data class TableScreenState( val tables: List, val id: UUID = UUID.randomUUID(), + val state: TableState = TableState.LOADING, ) data class TableConfigurationState( @@ -17,3 +18,8 @@ data class TableConfigurationState( !overwrittenRowHeaderWidth.isNullOrEmpty() or !overwrittenColumnWidth.isNullOrEmpty() } + +enum class TableState { + LOADING, + SUCCESS, +} diff --git a/compose-table/src/main/java/org/dhis2/composetable/ui/DataSetTableScreen.kt b/compose-table/src/main/java/org/dhis2/composetable/ui/DataSetTableScreen.kt index ae0f763239..315b7e7b50 100644 --- a/compose-table/src/main/java/org/dhis2/composetable/ui/DataSetTableScreen.kt +++ b/compose-table/src/main/java/org/dhis2/composetable/ui/DataSetTableScreen.kt @@ -6,13 +6,18 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.BottomSheetScaffold import androidx.compose.material.BottomSheetValue import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.Icon +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.ErrorOutline import androidx.compose.material.rememberBottomSheetScaffoldState import androidx.compose.material.rememberBottomSheetState import androidx.compose.runtime.Composable @@ -29,9 +34,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import kotlinx.coroutines.launch import org.dhis2.composetable.TableScreenState +import org.dhis2.composetable.TableState import org.dhis2.composetable.actions.TableInteractions import org.dhis2.composetable.actions.TextInputInteractions import org.dhis2.composetable.model.TableCell @@ -43,6 +50,9 @@ import org.dhis2.composetable.ui.compositions.LocalInteraction import org.dhis2.composetable.ui.compositions.LocalUpdatingCell import org.dhis2.composetable.ui.extensions.collapseIfExpanded import org.dhis2.composetable.ui.extensions.expandIfCollapsed +import org.hisp.dhis.mobile.ui.designsystem.component.AdditionalInfoItemColor +import org.hisp.dhis.mobile.ui.designsystem.component.InfoBar +import org.hisp.dhis.mobile.ui.designsystem.component.InfoBarData @OptIn(ExperimentalMaterialApi::class) @Composable @@ -53,6 +63,7 @@ fun DataSetTableScreen( TableCell, updateCellValue: (TableCell) -> Unit, ) -> TextInputModel?, + emptyTablesText: String? = null, onEdition: (editing: Boolean) -> Unit, onSaveValue: (TableCell) -> Unit, bottomContent: @Composable (() -> Unit)? = null, @@ -257,7 +268,7 @@ fun DataSetTableScreen( ), ) { AnimatedVisibility( - visible = tableScreenState.tables.isEmpty(), + visible = tableScreenState.state == TableState.LOADING, enter = fadeIn(), exit = fadeOut(), ) { @@ -277,10 +288,36 @@ fun DataSetTableScreen( LocalUpdatingCell provides updatingCell, LocalInteraction provides iter, ) { - DataTable( - tableList = tableScreenState.tables, - bottomContent = bottomContent, - ) + if (tableScreenState.state == TableState.SUCCESS && tableScreenState.tables.isEmpty()) { + Column( + modifier = Modifier.fillMaxWidth() + .padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + InfoBar( + infoBarData = InfoBarData( + text = emptyTablesText ?: "", + icon = { + Icon( + imageVector = Icons.Outlined.ErrorOutline, + contentDescription = "warning", + tint = AdditionalInfoItemColor.WARNING.color, + ) + }, + color = AdditionalInfoItemColor.WARNING.color, + backgroundColor = AdditionalInfoItemColor.WARNING.color.copy(alpha = 0.1f), + actionText = null, + onClick = {}, + ), + Modifier.testTag(EMPTY_TABLE_TEXT_TAG), + ) + } + } else { + DataTable( + tableList = tableScreenState.tables, + bottomContent = bottomContent, + ) + } } displayDescription?.let { TableDialog( @@ -295,3 +332,5 @@ fun DataSetTableScreen( } } } + +const val EMPTY_TABLE_TEXT_TAG = "EMPTY_TABLE_TEXT_TAG" diff --git a/stock-usecase/src/main/java/org/dhis2/android/rtsm/ui/managestock/ManageStockViewModel.kt b/stock-usecase/src/main/java/org/dhis2/android/rtsm/ui/managestock/ManageStockViewModel.kt index 08866d35c1..d7b70a3461 100644 --- a/stock-usecase/src/main/java/org/dhis2/android/rtsm/ui/managestock/ManageStockViewModel.kt +++ b/stock-usecase/src/main/java/org/dhis2/android/rtsm/ui/managestock/ManageStockViewModel.kt @@ -43,6 +43,7 @@ import org.dhis2.commons.resources.ResourceManager import org.dhis2.commons.viewmodel.DispatcherProvider import org.dhis2.composetable.TableConfigurationState import org.dhis2.composetable.TableScreenState +import org.dhis2.composetable.TableState import org.dhis2.composetable.actions.Validator import org.dhis2.composetable.model.KeyboardInputType import org.dhis2.composetable.model.TableCell @@ -265,6 +266,7 @@ class ManageStockViewModel @Inject constructor( _screenState.postValue( TableScreenState( tables = tables, + state = TableState.SUCCESS, ), )