Skip to content

Commit

Permalink
ANDROAPP-5611-mobile-ui-Create-coordinates-component (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
siddh1004 authored Oct 18, 2023
1 parent f6234b8 commit dcc92bf
Show file tree
Hide file tree
Showing 6 changed files with 412 additions and 0 deletions.
2 changes: 2 additions & 0 deletions common/src/commonMain/kotlin/org/hisp/dhis/common/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import org.hisp.dhis.common.screens.ImageBlockScreen
import org.hisp.dhis.common.screens.InputAgeScreen
import org.hisp.dhis.common.screens.InputBarCodeScreen
import org.hisp.dhis.common.screens.InputCheckBoxScreen
import org.hisp.dhis.common.screens.InputCoordinateScreen
import org.hisp.dhis.common.screens.InputDateTimeScreen
import org.hisp.dhis.common.screens.InputDropDownScreen
import org.hisp.dhis.common.screens.InputEmailScreen
Expand Down Expand Up @@ -181,6 +182,7 @@ fun Main() {
Components.IMAGE_BLOCK -> ImageBlockScreen()
Components.INPUT_DROPDOWN -> InputDropDownScreen()
Components.INPUT_DATE_TIME -> InputDateTimeScreen()
Components.INPUT_COORDINATE -> InputCoordinateScreen()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ enum class Components(val label: String) {
IMAGE_BLOCK("Image Block"),
INPUT_DROPDOWN("Input Dropdown"),
INPUT_DATE_TIME("Input Date Time"),
INPUT_COORDINATE("Input Coordinate"),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
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.Coordinates
import org.hisp.dhis.mobile.ui.designsystem.component.InputCoordinate
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.Title
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing
import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor

@Composable
fun InputCoordinateScreen() {
ColumnComponentContainer {
Title("Input Coordinates", textColor = TextColor.OnSurfaceVariant)

SubTitle("Basic Input Coordinates ", textColor = TextColor.OnSurfaceVariant)
var coordinates by rememberSaveable { mutableStateOf<Coordinates?>(null) }
InputCoordinate(
title = "Label",
state = InputShellState.UNFOCUSED,
coordinates = coordinates,
onResetButtonClicked = {
coordinates = null
},
onUpdateButtonClicked = {
coordinates = Coordinates(latitude = 39.46263, longitude = -0.33617)
},
)
Spacer(Modifier.size(Spacing.Spacing18))

SubTitle("Disabled Input Coordinates without data ", textColor = TextColor.OnSurfaceVariant)
var coordinates1 by rememberSaveable {
mutableStateOf<Coordinates?>(null)
}
InputCoordinate(
title = "Label",
state = InputShellState.DISABLED,
coordinates = coordinates1,
onResetButtonClicked = {
coordinates1 = null
},
onUpdateButtonClicked = {
coordinates1 = Coordinates(latitude = 39.46263, longitude = -0.33617)
},
)

SubTitle("Disabled Input Coordinates with data ", textColor = TextColor.OnSurfaceVariant)
var coordinates2 by rememberSaveable {
mutableStateOf<Coordinates?>(Coordinates(latitude = 39.46263, longitude = -0.33617))
}
InputCoordinate(
title = "Label",
state = InputShellState.DISABLED,
coordinates = coordinates2,
onResetButtonClicked = {
coordinates2 = null
},
onUpdateButtonClicked = {
coordinates2 = Coordinates(latitude = 39.46263, longitude = -0.33617)
},
)
Spacer(Modifier.size(Spacing.Spacing18))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package org.hisp.dhis.mobile.ui.designsystem.component

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AddLocationAlt
import androidx.compose.material.icons.outlined.Cancel
import androidx.compose.material.icons.outlined.EditLocationAlt
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import org.hisp.dhis.mobile.ui.designsystem.resource.provideStringResource
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing
import org.hisp.dhis.mobile.ui.designsystem.theme.TextColor

/**
* DHIS2 Input coordinate. Wraps DHIS · [InputShell].
* @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 coordinates controls the latitude and longitude of the location
* @param latitudeText controls the text to be shown for the latitude label
* @param longitudeText controls the text to be shown for the longitude label
* @param addLocationBtnText controls the text to be shown for the add polygon button
* @param isRequired controls whether the field is mandatory or not
* @param modifier allows a modifier to be passed externally
* @param onResetButtonClicked callback to when reset button is clicked
* @param onUpdateButtonClicked callback to when add button or edit icon is clicked
*/
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun InputCoordinate(
title: String,
state: InputShellState = InputShellState.UNFOCUSED,
supportingText: List<SupportingTextData>? = null,
legendData: LegendData? = null,
coordinates: Coordinates? = null,
latitudeText: String = provideStringResource("latitude"),
longitudeText: String = provideStringResource("longitude"),
addLocationBtnText: String = provideStringResource("add_location"),
isRequired: Boolean = false,
modifier: Modifier = Modifier,
onResetButtonClicked: () -> Unit,
onUpdateButtonClicked: () -> Unit,
) {
InputShell(
modifier = modifier.testTag("INPUT_COORDINATE"),
title = title,
state = state,
isRequiredField = isRequired,
legend = {
legendData?.let {
Legend(legendData, modifier.testTag("INPUT_COORDINATE_LEGEND"))
}
},
supportingText = {
supportingText?.forEach { label ->
SupportingText(
label.text,
label.state,
modifier = modifier.testTag("INPUT_COORDINATE_SUPPORTING_TEXT"),
)
}
},
inputField = {
if (coordinates != null) {
FlowRow(
horizontalArrangement = Arrangement.spacedBy(Spacing.Spacing16),
modifier = Modifier.padding(end = Spacing.Spacing16),
) {
CoordinateText(
latitudeText,
coordinates.latitude.toString(),
state == InputShellState.DISABLED,
)
CoordinateText(
longitudeText,
coordinates.longitude.toString(),
state == InputShellState.DISABLED,
)
}
} else {
Button(
enabled = state != InputShellState.DISABLED,
ButtonStyle.KEYBOARDKEY,
addLocationBtnText,
icon = {
Icon(
imageVector = Icons.Outlined.AddLocationAlt,
contentDescription = "Add Location Button",
)
},
Modifier
.fillMaxWidth()
.padding(end = Spacing.Spacing12, top = Spacing.Spacing8, bottom = Spacing.Spacing8)
.testTag("INPUT_COORDINATE_ADD_BUTTON"),
) {
onUpdateButtonClicked.invoke()
}
}
},
primaryButton = if (coordinates != null && state != InputShellState.DISABLED) {
{
IconButton(
modifier = Modifier.testTag("INPUT_COORDINATE_RESET_BUTTON"),
icon = {
Icon(
imageVector = Icons.Outlined.Cancel,
contentDescription = "Reset Button",
)
},
onClick = onResetButtonClicked,
)
}
} else {
null
},
secondaryButton = if (coordinates != null && state != InputShellState.DISABLED) {
{
SquareIconButton(
modifier = Modifier.testTag("INPUT_COORDINATE_EDIT_BUTTON"),
enabled = true,
icon = {
Icon(
imageVector = Icons.Outlined.EditLocationAlt,
contentDescription = "edit_location",
)
},
onClick = {},
)
}
} else {
null
},
)
}

@Composable
fun CoordinateText(text: String, value: String, isDisabled: Boolean) {
Text(
style = MaterialTheme.typography.bodyLarge.copy(
color = if (!isDisabled) {
TextColor.OnSurface
} else {
TextColor.OnDisabledSurface
},
),
text = buildAnnotatedString {
withStyle(style = SpanStyle(color = TextColor.OnDisabledSurface)) {
append("$text: ")
}
append(value)
},
)
}

data class Coordinates(
val latitude: Double,
val longitude: Double,
)
3 changes: 3 additions & 0 deletions designsystem/src/commonMain/resources/values/strings_en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@
<string name="sync">Sync</string>
<string name="add_polygon">Add polygon</string>
<string name="polygon_captured">Polygon captured</string>
<string name="add_location">Add location</string>
<string name="latitude">Lat</string>
<string name="longitude">Long</string>
</resources>
Loading

0 comments on commit dcc92bf

Please sign in to comment.