-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Siddharth Agarwal
committed
Oct 6, 2023
1 parent
56580e0
commit e013521
Showing
6 changed files
with
373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
common/src/commonMain/kotlin/org/hisp/dhis/common/screens/InputOrgUnitScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package org.hisp.dhis.common.screens | ||
|
||
import androidx.compose.foundation.layout.Spacer | ||
import androidx.compose.foundation.layout.size | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.saveable.rememberSaveable | ||
import androidx.compose.runtime.setValue | ||
import androidx.compose.ui.Modifier | ||
import org.hisp.dhis.mobile.ui.designsystem.component.ColumnComponentContainer | ||
import org.hisp.dhis.mobile.ui.designsystem.component.InputOrgUnit | ||
import org.hisp.dhis.mobile.ui.designsystem.component.InputShellState | ||
import org.hisp.dhis.mobile.ui.designsystem.component.SubTitle | ||
import org.hisp.dhis.mobile.ui.designsystem.component.SupportingTextData | ||
import org.hisp.dhis.mobile.ui.designsystem.component.SupportingTextState | ||
import org.hisp.dhis.mobile.ui.designsystem.component.Title | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor | ||
|
||
@Composable | ||
fun InputOrgUnitScreen() { | ||
ColumnComponentContainer { | ||
Title("Input Org. unit component", textColor = TextColor.OnSurfaceVariant) | ||
SubTitle("Basic Org. unit ", textColor = TextColor.OnSurfaceVariant) | ||
var inputText1 by rememberSaveable { mutableStateOf("") } | ||
|
||
InputOrgUnit( | ||
title = "Label", | ||
inputText = inputText1, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputText1 = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
Spacer(Modifier.size(Spacing.Spacing18)) | ||
|
||
SubTitle("Basic Org. unit with content ", textColor = TextColor.OnSurfaceVariant) | ||
var inputText2 by rememberSaveable { mutableStateOf("PHC Fakename") } | ||
|
||
InputOrgUnit( | ||
title = "Label", | ||
inputText = inputText2, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputText2 = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
Spacer(Modifier.size(Spacing.Spacing18)) | ||
|
||
SubTitle("Error Org. unit required field ", textColor = TextColor.OnSurfaceVariant) | ||
var inputText3 by rememberSaveable { mutableStateOf("") } | ||
|
||
InputOrgUnit( | ||
title = "Label", | ||
state = InputShellState.ERROR, | ||
supportingText = listOf(SupportingTextData("Required", SupportingTextState.ERROR)), | ||
inputText = inputText3, | ||
isRequiredField = true, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputText3 = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
Spacer(Modifier.size(Spacing.Spacing18)) | ||
|
||
SubTitle("Disabled Org. unit with content ", textColor = TextColor.OnSurfaceVariant) | ||
var inputText5 by rememberSaveable { mutableStateOf("PHC Fakename") } | ||
InputOrgUnit( | ||
title = "Label", | ||
state = InputShellState.DISABLED, | ||
inputText = inputText5, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputText5 = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
...stem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputOrgUnit.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package org.hisp.dhis.mobile.ui.designsystem.component | ||
|
||
import androidx.compose.foundation.text.KeyboardOptions | ||
import androidx.compose.material3.Icon | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.platform.testTag | ||
import androidx.compose.ui.text.input.ImeAction | ||
import org.hisp.dhis.mobile.ui.designsystem.resource.provideDHIS2Icon | ||
|
||
/** | ||
* DHIS2 Input org unit. Wraps DHIS · [BasicTextInput]. | ||
* @param title controls the text to be shown for the title | ||
* @param state Manages the InputShell state | ||
* @param supportingText is a list of SupportingTextData that | ||
* manages all the messages to be shown | ||
* @param legendData manages the legendComponent | ||
* @param inputText manages the value of the text in the input field | ||
* @param isRequiredField controls whether the field is mandatory or not | ||
* @param onNextClicked gives access to the imeAction event | ||
* @param onValueChanged gives access to the onValueChanged event | ||
* @param onFocusChanged gives access to the onFocusChanged returns true if | ||
* item is focused | ||
* @param imeAction controls the imeAction button to be shown | ||
* @param modifier allows a modifier to be passed externally | ||
* @param onOrgUnitActionCLicked callback to when org unit button is clicked | ||
*/ | ||
@Composable | ||
fun InputOrgUnit( | ||
title: String, | ||
state: InputShellState = InputShellState.UNFOCUSED, | ||
supportingText: List<SupportingTextData>? = null, | ||
legendData: LegendData? = null, | ||
inputText: String? = null, | ||
isRequiredField: Boolean = false, | ||
onNextClicked: (() -> Unit)? = null, | ||
onValueChanged: ((String?) -> Unit)? = null, | ||
onFocusChanged: ((Boolean) -> Unit)? = null, | ||
imeAction: ImeAction = ImeAction.Next, | ||
modifier: Modifier = Modifier, | ||
onOrgUnitActionCLicked: () -> Unit, | ||
) { | ||
BasicTextInput( | ||
title = title, | ||
state = state, | ||
supportingText = supportingText, | ||
legendData = legendData, | ||
inputText = inputText, | ||
isRequiredField = isRequiredField, | ||
onNextClicked = onNextClicked, | ||
onValueChanged = onValueChanged, | ||
keyboardOptions = KeyboardOptions(imeAction = imeAction), | ||
modifier = modifier, | ||
testTag = "ORG_UNIT", | ||
onFocusChanged = onFocusChanged, | ||
actionButton = { | ||
SquareIconButton( | ||
modifier = Modifier.testTag("ORG_UNIT_BUTTON"), | ||
enabled = state != InputShellState.DISABLED, | ||
icon = { | ||
Icon( | ||
painter = provideDHIS2Icon("org_unit"), | ||
contentDescription = "org_unit_icon", | ||
) | ||
}, | ||
onClick = onOrgUnitActionCLicked, | ||
) | ||
}, | ||
) | ||
} |
10 changes: 10 additions & 0 deletions
10
designsystem/src/commonMain/resources/drawable/org_unit.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:width="24dp" | ||
android:height="24dp" | ||
android:viewportWidth="24" | ||
android:viewportHeight="24"> | ||
<path | ||
android:pathData="M3,4V6.352H4.994V4H3ZM12.545,6.207V11.125H14.957C14.977,11.125 14.995,11.131 15.016,11.131C15.036,11.131 15.054,11.125 15.074,11.125H17.463V8.756C17.464,8.729 17.471,8.703 17.471,8.676C17.471,8.648 17.464,8.623 17.463,8.596V6.207H12.545ZM3,7.5V9.852H4.994V7.5H3ZM6.213,7.678V9.672H8.564V7.678H6.213ZM9.713,7.678V9.672H12.064V7.678H9.713ZM3,10.998V13.352H4.994V10.998H3ZM3,14.498V16.852H3.01C3.008,16.887 3,16.918 3,16.953C3,18.313 4.095,19.41 5.455,19.41C5.49,19.41 5.524,19.4 5.559,19.398V19.41H7.91V17.418H7.865H5.559H5.455H5.434V17.414C5.193,17.403 5.003,17.211 4.996,16.969H4.994V16.953V14.543V14.498H3ZM15.398,15.949V20.867H17.861H20.316V18.414V15.949H15.398ZM9.059,17.418V19.41H11.41V17.418H9.059ZM12.559,17.418V19.41H14.91V17.418H12.559Z" | ||
android:fillColor="#000000" | ||
android:fillType="evenOdd"/> | ||
</vector> |
203 changes: 203 additions & 0 deletions
203
...src/desktopTest/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/InputOrgUnitTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
package org.hisp.dhis.mobile.ui.designsystem.component | ||
|
||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.runtime.saveable.rememberSaveable | ||
import androidx.compose.runtime.setValue | ||
import androidx.compose.ui.test.assert | ||
import androidx.compose.ui.test.assertHasClickAction | ||
import androidx.compose.ui.test.assertIsEnabled | ||
import androidx.compose.ui.test.assertIsNotEnabled | ||
import androidx.compose.ui.test.assertTextEquals | ||
import androidx.compose.ui.test.hasText | ||
import androidx.compose.ui.test.junit4.createComposeRule | ||
import androidx.compose.ui.test.onNodeWithTag | ||
import androidx.compose.ui.test.performClick | ||
import androidx.compose.ui.test.performTextInput | ||
import org.hisp.dhis.mobile.ui.designsystem.theme.SurfaceColor | ||
import org.junit.Rule | ||
import org.junit.Test | ||
|
||
class InputOrgUnitTest { | ||
@get:Rule | ||
val rule = createComposeRule() | ||
|
||
@Test | ||
fun shouldDisplayInputOrgUnitCorrectly() { | ||
rule.setContent { | ||
InputOrgUnit( | ||
title = "Label", | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("INPUT_ORG_UNIT").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_LEGEND").assertDoesNotExist() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_SUPPORTING_TEXT").assertDoesNotExist() | ||
} | ||
|
||
@Test | ||
fun shouldAllowUserInputWhenEnabled() { | ||
rule.setContent { | ||
var inputValue by rememberSaveable { mutableStateOf("") } | ||
InputOrgUnit( | ||
title = "Label", | ||
inputText = inputValue, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("INPUT_ORG_UNIT").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_FIELD").performTextInput("PHC fake") | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_FIELD").assert(hasText("PHC fake")) | ||
} | ||
|
||
@Test | ||
fun shouldNotAllowUserInputWhenDisabled() { | ||
rule.setContent { | ||
InputOrgUnit( | ||
title = "Label", | ||
state = InputShellState.DISABLED, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("INPUT_ORG_UNIT").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_FIELD").assertIsNotEnabled() | ||
} | ||
|
||
@Test | ||
fun shouldShowResetButtonWhenTextFieldHasContent() { | ||
rule.setContent { | ||
var inputValue by rememberSaveable { mutableStateOf("") } | ||
InputOrgUnit( | ||
title = "Label", | ||
inputText = inputValue, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("INPUT_ORG_UNIT").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_FIELD").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_FIELD").performTextInput("PHC fake") | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_RESET_BUTTON").assertExists() | ||
} | ||
|
||
@Test | ||
fun shouldDeleteContentWhenResetButtonIsClickedAndHideResetButton() { | ||
rule.setContent { | ||
var inputValue by rememberSaveable { mutableStateOf("PHC fake") } | ||
|
||
InputOrgUnit( | ||
title = "Label", | ||
inputText = inputValue, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("INPUT_ORG_UNIT").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_RESET_BUTTON").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_RESET_BUTTON").performClick() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_FIELD").assertTextEquals("") | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_RESET_BUTTON").assertDoesNotExist() | ||
} | ||
|
||
@Test | ||
fun shouldHideResetButtonWhenDisabled() { | ||
rule.setContent { | ||
var inputValue by rememberSaveable { mutableStateOf("PHC fake") } | ||
InputOrgUnit( | ||
title = "Label", | ||
state = InputShellState.DISABLED, | ||
inputText = inputValue, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("INPUT_ORG_UNIT").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_RESET_BUTTON").assertDoesNotExist() | ||
} | ||
|
||
@Test | ||
fun shouldShowLegendCorrectly() { | ||
rule.setContent { | ||
InputOrgUnit( | ||
title = "Label", | ||
inputText = "Input", | ||
legendData = LegendData(SurfaceColor.CustomGreen, "Legend"), | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("INPUT_ORG_UNIT").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_LEGEND").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_LEGEND").assertHasClickAction() | ||
} | ||
|
||
@Test | ||
fun shouldShowSupportingTextCorrectly() { | ||
rule.setContent { | ||
InputOrgUnit( | ||
title = "Label", | ||
inputText = "Input", | ||
supportingText = listOf(SupportingTextData("Supporting text", SupportingTextState.DEFAULT)), | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("INPUT_ORG_UNIT").assertExists() | ||
rule.onNodeWithTag("INPUT_ORG_UNIT_SUPPORTING_TEXT").assertExists() | ||
} | ||
|
||
@Test | ||
fun shouldEnableOrgUnitActionButtonWhenEnabled() { | ||
rule.setContent { | ||
var inputValue by remember { mutableStateOf("") } | ||
|
||
InputOrgUnit( | ||
title = "Label", | ||
inputText = inputValue, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("ORG_UNIT_BUTTON").assertIsEnabled() | ||
} | ||
|
||
@Test | ||
fun shouldDisableOrgUnitActionButtonOnWhenDisabled() { | ||
rule.setContent { | ||
var inputValue by remember { mutableStateOf("PHC fake") } | ||
|
||
InputOrgUnit( | ||
title = "Label", | ||
state = InputShellState.DISABLED, | ||
inputText = inputValue, | ||
onValueChanged = { | ||
if (it != null) { | ||
inputValue = it | ||
} | ||
}, | ||
onOrgUnitActionCLicked = {}, | ||
) | ||
} | ||
rule.onNodeWithTag("ORG_UNIT_BUTTON").assertIsNotEnabled() | ||
} | ||
} |