Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ANDROAPP-5611-mobile-ui-Create-coordinates-component #104

Merged
merged 3 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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