diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/AgeFieldHelper.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/AgeFieldHelper.kt index 19df36d23..fc74fa51e 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/AgeFieldHelper.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/AgeFieldHelper.kt @@ -18,18 +18,18 @@ import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor * * @param orientation: Controls how the radio buttons will be displayed, HORIZONTAL for rows or * VERTICAL for columns. - * @param optionSelected: controls which item is selected. + * @param optionSelected: controls which [TimeUnitValues] is selected. * @param enabled: manages the enabled state - * @param onClick: is a callback to notify which item has changed into the block. + * @param onClick: is a callback to notify when [TimeUnitValues] is changed. * @param modifier: optional modifier. */ @Composable internal fun TimeUnitSelector( orientation: Orientation, - optionSelected: String, + optionSelected: TimeUnitValues, modifier: Modifier = Modifier, enabled: Boolean = true, - onClick: (RadioButtonData) -> Unit, + onClick: (TimeUnitValues) -> Unit, ) { val backgroundColor = if (enabled) { SurfaceColor.Surface @@ -37,6 +37,14 @@ internal fun TimeUnitSelector( SurfaceColor.DisabledSurface } + val options = TimeUnitValues.entries.map { + RadioButtonData(it.name, optionSelected == it, enabled, provideStringResource(it.value)) + } + + var selectedOption by remember { + mutableStateOf(options.find { it.selected } ?: options[0]) + } + RowComponentContainer( modifier = modifier .background(color = backgroundColor, Shape.SmallBottom) @@ -45,18 +53,10 @@ internal fun TimeUnitSelector( end = Spacing.Spacing8, ), ) { - val options = TimeUnitValues.values().map { - RadioButtonData(it.value, optionSelected == it.value, enabled, provideStringResource(it.value)) - } - val selectedItem = options.find { - it.selected - } - var currentItem by remember { - mutableStateOf(selectedItem ?: options[0]) - } - RadioButtonBlock(orientation, options, currentItem) { - currentItem = it - onClick.invoke(it) + RadioButtonBlock(orientation, options, selectedOption) { + selectedOption = it + val selectedTimeUnit = TimeUnitValues.entries.first { it.name == selectedOption.uid } + onClick.invoke(selectedTimeUnit) } } } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAge.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAge.kt index 3bfbedc99..16a5ac9fb 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAge.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAge.kt @@ -157,7 +157,7 @@ fun InputAge( .testTag("INPUT_AGE_TEXT_FIELD") .fillMaxWidth(), inputTextValue = getTextFieldValue(uiModel.inputType), - helper = helperText, + helper = if (helperText != null) provideStringResource(helperText).lowercase() else null, isSingleLine = true, helperStyle = helperStyle, onInputChanged = { newText -> @@ -218,12 +218,9 @@ fun InputAge( modifier = Modifier.fillMaxWidth() .testTag("INPUT_AGE_TIME_UNIT_SELECTOR"), orientation = Orientation.HORIZONTAL, - optionSelected = YEARS.value, + optionSelected = YEARS, enabled = uiModel.state != InputShellState.DISABLED, - onClick = { itemData -> - val timeUnit = TimeUnitValues.entries - .first { it.value.contains(itemData.textInput!!, ignoreCase = true) } - + onClick = { timeUnit -> uiModel.onValueChanged.invoke(uiModel.inputType.copy(unit = timeUnit)) }, ) diff --git a/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAgeTest.kt b/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAgeTest.kt index fbffaf18c..c3dbd2a6f 100644 --- a/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAgeTest.kt +++ b/designsystem/src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputAgeTest.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performTextClearance import androidx.compose.ui.test.performTextInput import org.junit.Rule import org.junit.Test @@ -27,7 +28,6 @@ class InputAgeTest { // no-op }, ), - ) } @@ -49,7 +49,6 @@ class InputAgeTest { // no-op }, ), - ) } @@ -72,7 +71,6 @@ class InputAgeTest { inputType = it }, ), - ) } @@ -93,7 +91,6 @@ class InputAgeTest { // no-op }, ), - ) } @@ -116,7 +113,6 @@ class InputAgeTest { inputType = it }, ), - ) } @@ -138,7 +134,6 @@ class InputAgeTest { inputType = it }, ), - ) } @@ -176,4 +171,39 @@ class InputAgeTest { rule.onNodeWithTag("INPUT_AGE_SUPPORTING_TEXT").assertExists() } + + @Test + fun changingAgeTimeUnitShouldWorkProperly() { + var inputType by mutableStateOf(AgeInputType.Age.EMPTY) + + rule.setContent { + InputAge( + InputAgeModel( + title = "Label", + inputType = inputType, + onValueChanged = { + inputType = it + }, + ), + ) + } + + rule.onNodeWithTag("INPUT_AGE_TIME_UNIT_SELECTOR").assertExists() + rule.onNodeWithTag("RADIO_BUTTON_YEARS").assertExists() + rule.onNodeWithTag("RADIO_BUTTON_MONTHS").assertExists() + rule.onNodeWithTag("RADIO_BUTTON_DAYS").assertExists() + + rule.onNodeWithTag("RADIO_BUTTON_MONTHS").performClick() + rule.onNodeWithTag("INPUT_AGE_TEXT_FIELD").performTextInput("11") + val newInputMonthType = inputType as AgeInputType.Age + assert(newInputMonthType.value.text == "11") + assert(newInputMonthType.unit == TimeUnitValues.MONTHS) + + rule.onNodeWithTag("RADIO_BUTTON_DAYS").performClick() + rule.onNodeWithTag("INPUT_AGE_TEXT_FIELD").performTextClearance() + rule.onNodeWithTag("INPUT_AGE_TEXT_FIELD").performTextInput("28") + val newInputDaysType = inputType as AgeInputType.Age + assert(newInputDaysType.value.text == "28") + assert(newInputDaysType.unit == TimeUnitValues.DAYS) + } }